home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pinstaller / GLIGenDialog.py < prev    next >
Text File  |  2006-02-14  |  94KB  |  1,836 lines

  1. # Copyright 1999-2005 Gentoo Foundation
  2. # This source code is distributed under the terms of version 2 of the GNU
  3. # General Public License as published by the Free Software Foundation, a copy
  4. # of which can be found in the main directory of this project.
  5. import dialog, platform, string, os, glob, copy, re
  6. import GLIInstallProfile
  7. import GLIClientConfiguration
  8. import GLIStorageDevice
  9. import GLIUtility
  10. from GLIException import GLIException
  11. import gettext
  12. _ = gettext.gettext
  13. #This is a parent class to centralize the code between UserGenCC and UserGenIP
  14.  
  15. class GLIGen(object):
  16.     def __init__(self):
  17.         self._d = dialog.Dialog()
  18.         self._DLG_OK = 0
  19.         self._DLG_YES = 0
  20.         self._DLG_CANCEL = 1
  21.         self._DLG_NO = 1
  22.         self._DLG_ESC = 2
  23.         self._DLG_ERROR = 3
  24.         self._DLG_EXTRA = 4
  25.         self._DLG_HELP = 5
  26.     
  27.     def _dmenu_list_to_choices(self, list):
  28.         choices = []
  29.         for i in range(0, len(list)):
  30.             choices.append((str(i + 1), list[i]))
  31.  
  32.         return choices
  33.         
  34.     def client_profile(self):
  35.         return self._client_profile
  36.     
  37.     def install_profile(self):
  38.         return self._install_profile
  39.  
  40. #This class will generate a client config and return it as a xml string
  41. class GLIGenCF(GLIGen):
  42.     def __init__(self, client_profile, local_install=True, advanced_mode=True):
  43.         GLIGen.__init__(self)
  44.         self._client_profile = client_profile
  45.         self.local_install = local_install
  46.         self.advanced_mode = advanced_mode
  47.         
  48.     def serialize(self):
  49.         return self._client_profile.serialize()
  50.     #-----------------------------------------------
  51.     #Functions for generating a client configuration
  52.     #-----------------------------------------------    
  53.     def set_arch_template(self):
  54.         subarches = { 'i386': 'x86', 'i486': 'x86', 'i586': 'x86', 'i686': 'x86', 'x86_64': 'amd64', 'parisc': 'hppa' }
  55.         arch = platform.machine()
  56.         if arch in subarches: 
  57.             arch = subarches[arch]
  58.         if self.local_install:
  59.             try:
  60.                 self._client_profile.set_architecture_template(None, arch, None)
  61.             except:
  62.                 self._d.msgbox(_(u"Error!  Undefined architecture template specified or found on the current machine"))
  63.         else:
  64.             template_choices = ["x86", "amd64", "sparc", "alpha", "hppa", "ppc"]
  65.             arch_template_string = _(u"Please select the architecture of the computer that gentoo will be installed on.  For pentium and AMD 32-bit processors, choose x86.  If you don't know your architecture, you should consider another Linux distribution.")
  66.             code, menuitem = self._d.menu(arch_template_string, choices=self._dmenu_list_to_choices(template_choices), default_item=str(template_choices.index(arch)+1), height=20)
  67.             if code == self._DLG_OK:
  68.                 menuitem = template_choices[int(menuitem)-1]
  69.                 try:
  70.                     self._client_profile.set_architecture_template(None, menuitem, None)
  71.                 except: 
  72.                     self._d.msgbox(_(u"Error!  Undefined architecture template specified or found on the current machine"))
  73.     def set_verbose(self):
  74.         #Don't show unless advanced.
  75.         if self.advanced_mode:
  76.             #Change the Yes/No buttons back.
  77.             self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  78.             self._d.add_persistent_args(["--no-label", _(u"No")])
  79.             if self._d.yesno(_(u"Do you want debugging output enabled during the install?  This is mainly meant to help the developers debug any bugs."), width=60) == self._DLG_YES:
  80.                 self._client_profile.set_verbose(None, True, None)
  81.             else:
  82.                 self._client_profile.set_verbose(None, False, None)
  83.  
  84.     def set_logfile(self):
  85.         #If not advanced, the default will suffice.
  86.         if self.advanced_mode:
  87.             logfile_string = _(u"""The installer logs all important events during the install process to a logfile for debugging purposes.
  88. The file gets copied to the new system once the install is complete.
  89. Enter the desired filename and path for the install log (the default is recommended):""")
  90.             initval = self._client_profile.get_log_file()
  91.             code, logfile = self._d.inputbox(logfile_string, init=initval, width=60, height=15)
  92.             if code == self._DLG_OK:
  93.                 self._client_profile.set_log_file(None, logfile, None)
  94.  
  95.     def set_root_mount_point(self):
  96.         #If not advanced, the default will suffice.
  97.         if self.advanced_mode:
  98.             root_mount_point_string = _(u"Enter the mount point to be used to mount the partition(s) where the new system will be installed.  The default is /mnt/gentoo and is greatly recommended, but any mount point will do.")    
  99.             initval = self._client_profile.get_root_mount_point()
  100.             code, rootmountpoint = self._d.inputbox(root_mount_point_string, init=initval, width=60, height=11)
  101.             if code == self._DLG_OK: 
  102.                 self._client_profile.set_root_mount_point(None, rootmountpoint, None)
  103.  
  104.     def set_client_networking(self):
  105.         if GLIUtility.ping("www.gentoo.org") and self.local_install:    #If an active connection exists, ignore this step if doing a local install.
  106.             return
  107.         if self.local_install:
  108.             device_list = GLIUtility.get_eth_devices()
  109.         else:
  110.             device_list = []
  111.         choice_list = []
  112.         for device in device_list:
  113.             choice_list.append((device, GLIUtility.get_interface_realname(device)))
  114.         choice_list.append(("Other",_(u"Type your own.")))
  115.         cnet_string1 = _(u"In order to complete most installs, an active Internet connection is required.  Listed are the network devices already detected.  In this step you will need to setup one network connection for GLI to use to connect to the Internet.  If your desired device does not show up in the list, you can select Other and input the device name manually.")
  116.         code, interface = self._d.menu(cnet_string1, width=75, height=20, choices=choice_list)
  117.         if code != self._DLG_OK: 
  118.             return
  119.         if interface == "Other":
  120.             code, interface = self._d.inputbox(_(u"Enter the interface (NIC) you would like to use for installation (e.g. eth0):"))
  121.             if code != self._DLG_OK: 
  122.                 return
  123.         
  124.         dhcp_options = ""
  125.         
  126.         #Change the Yes/No buttons to new labels for this question.
  127.         self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
  128.         self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
  129.         cnet_string2 = _(u"To setup your network interface, you can either use DHCP if enabled, or manually enter your network information.\n  DHCP (Dynamic Host Configuration Protocol) makes it possible to automatically receive networking information (IP address, netmask, broadcast address, gateway, nameservers etc.). This only works if you have a DHCP server in your network (or if your provider provides a DHCP service).  If you do not, you must enter the information manually.  Please select your networking configuration method:")
  130.         if self._d.yesno(cnet_string2, height=15, width=60) == self._DLG_YES: #DHCP
  131.             network_type = 'dhcp'
  132.             code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list.  If you have none, just press Enter."), height=13, width=50)
  133.         else:
  134.             network_type = 'static'
  135.             code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information)  Your broadcast address is probably your IP address with 255 as the last tuple.  Do not press Enter until all fields you intend to fill out are complete!'), 
  136.             ((_(u'Enter your IP address:'), 15),
  137.              (_(u'Enter your Broadcast address:'), 15),
  138.              (_(u'Enter your Netmask:'),15,'255.255.255.0'),
  139.              (_(u'Enter your default gateway:'),15), 
  140.              (_(u'Enter a DNS server:'),15,'128.118.25.3'),
  141.              (_(u'Enter a HTTP Proxy IP:'), 15,self._client_profile.get_http_proxy()),
  142.              (_(u'Enter a FTP Proxy IP:'), 15, self._client_profile.get_ftp_proxy()), 
  143.              (_(u'Enter a RSYNC Proxy:'),15,self._client_profile.get_rsync_proxy())
  144.             ))
  145.             (ip_address, broadcast, netmask, gateway, dnsservers, http_proxy, ftp_proxy, rsync_proxy) = data[:-1].split('\n')
  146.             if code != self._DLG_OK: 
  147.                 return
  148.         #Set the info now that it's all gathered.
  149.         try:
  150.             self._client_profile.set_network_type(None, network_type, None)
  151.             self._client_profile.set_network_interface(None, interface, None)
  152.             if not network_type == 'dhcp':
  153.                 self._client_profile.set_network_ip(None, ip_address, None)
  154.                 self._client_profile.set_network_broadcast(None, broadcast, None)
  155.                 self._client_profile.set_network_netmask(None, netmask, None)
  156.                 self._client_profile.set_network_gateway(None, gateway, None)
  157.                 self._client_profile.set_dns_servers(None, dnsservers, None)
  158.             else:
  159.                 if dhcp_options:
  160.                     self._client_profile.set_network_dhcp_options(None, dhcp_options, None)
  161.             if http_proxy:
  162.                 self._client_profile.set_http_proxy(None, http_proxy, None)
  163.             if ftp_proxy:
  164.                 self._client_profile.set_ftp_proxy(None, ftp_proxy, None)
  165.             if rsync_proxy:
  166.                 self._client_profile.set_rsync_proxy(None, rsync_proxy, None)
  167.                                 
  168.         except: 
  169.             self._d.msgbox(_(u"ERROR! Could not set networking information!"))
  170.  
  171.     def set_enable_ssh(self):
  172.         #Change the Yes/No buttons back.
  173.         self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  174.         self._d.add_persistent_args(["--no-label", _(u"No")])
  175.         if self.advanced_mode:
  176.             if self._d.yesno(_(u"Do you want SSH enabled during the install?  This will allow you to login remotely during the installation process.  If choosing Yes, be sure you select a new LiveCD root password!"), width=60) == self._DLG_YES:
  177.                 self._client_profile.set_enable_ssh(None, True, None)
  178.             else:
  179.                 self._client_profile.set_enable_ssh(None, False, None)
  180.  
  181.     def set_livecd_password(self):
  182.         # The root password will be set here only if in advanced mode.  Otherwise it is auto-scrambled.
  183.         if self.advanced_mode:
  184.             match = False;
  185.             while not match:
  186.                 livecd_password_string = _(u"""If you want to be able to login to your machine from another console during the installation,
  187. you will want to enter a new root password for the LIVECD.
  188. Note that this can be different from your new system's root password.
  189. Presss Enter twice to skip this step.
  190. Enter the new LIVECD root password:    """)
  191.                 code, passwd1 = self._d.passwordbox(livecd_password_string, width=60, height=16)
  192.                 if code != self._DLG_OK: 
  193.                     return
  194.                 code, passwd2 = self._d.passwordbox(_(u"Enter the new LIVECD root password again to verify:"))
  195.                 if code != self._DLG_OK: 
  196.                     return
  197.                 if passwd1 != passwd2:
  198.                     self._d.msgbox(_(u"The passwords do not match.  Please try again."))
  199.                     return
  200.                 else:
  201.                     match = True;
  202.                     if passwd1 != "":  #don't want to hash an empty password.
  203.                         try:
  204.                             self._client_profile.set_root_passwd(None, GLIUtility.hash_password(passwd1), None)
  205.                         except:
  206.                             d.msgbox(_(u"ERROR! Could not set the root password on the LiveCD!"))
  207.                         self._d.msgbox(_(u"Password saved.  Press Enter to continue."))
  208.                         
  209.     def set_client_kernel_modules(self):
  210.         if self.advanced_mode:
  211.             status, output = GLIUtility.spawn("lsmod", return_output=True)
  212.             cmodules_string1 = _(u"Here is a list of modules currently loaded on your machine.\n  Please look through and see if any modules are missing\n that you would like loaded.\n\n")
  213.             self._d.add_persistent_args(["--exit-label", _(u"Continue")])
  214.             self._d.scrollbox(cmodules_string1+output, height=20, width=70, title=_(u"Loaded Modules"))
  215.             cmodules_string2 = _(u"\nIf you have additional modules you would like loaded before the installation begins (ex. a network driver), enter them in a space-separated list.")
  216.             code, kernel_modules_list = self._d.inputbox(cmodules_string2, init="", width=60, height=12)
  217.             if code == self._DLG_OK:
  218.                 try:
  219.                     self._client_profile.set_kernel_modules(None, kernel_modules_list, None)
  220.                 except:
  221.                     d.msgbox(_(u"ERROR! Could not set the list of kernel modules!"))
  222.  
  223.     def save_client_profile(self, xmlfilename="", askforfilename=True):
  224.         code = 0
  225.         filename = xmlfilename
  226.         if askforfilename:
  227.             code, filename = self._d.inputbox(_(u"Enter a filename for the XML file"), init=xmlfilename)
  228.             if code != self._DLG_OK or not filename: 
  229.                 return
  230.         if GLIUtility.is_file(filename):
  231.             #Change the Yes/No buttons back.
  232.             self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  233.             self._d.add_persistent_args(["--no-label", _(u"No")])
  234.             if not self._d.yesno(_(u"The file %s already exists. Do you want to overwrite it?") % filename) == self._DLG_YES:
  235.                 return
  236.         configuration = open(filename ,"w")
  237.         configuration.write(self._client_profile.serialize())
  238.         configuration.close()
  239.  
  240. class GLIGenIP(GLIGen):
  241.     def __init__(self, client_profile, install_profile, local_install=True, advanced_mode=True):
  242.         GLIGen.__init__(self)
  243.         self._client_profile = client_profile
  244.         self._install_profile = install_profile
  245.         self.local_install = local_install
  246.         self.advanced_mode = advanced_mode
  247.  
  248.     
  249.     def serialize(self):
  250.         return self._install_profile.serialize()
  251.     #---------------------------------------
  252.     #Functions to generate a install profile
  253.     #---------------------------------------
  254.     
  255.     def set_partitions(self):
  256.         partitions_string1 = _("""The first thing on the new system to setup is the partitoning.
  257. You will first select a drive and then edit its partitions.
  258. No changes will be saved until the end of the step.
  259. No changes to your disk will be made until the installation.
  260. NOTE: YOU MUST AT LEAST SELECT ONE PARTITION AS YOUR ROOT PARTITION "/"
  261. If your drive is pre-partitioned, just select the mountpoints and make 
  262. sure that the format option is set to FALSE or it will erase your data.
  263. The installer does not yet support resizing of partitions (its not safe).
  264. Please refer to the Gentoo Installation Handbook for more information
  265. on partitioning and the various filesystem types available in Linux.""")
  266.         self._d.msgbox(partitions_string1, height=17, width=78)
  267.         devices = self._install_profile.get_partition_tables()
  268.         drives = devices.keys()
  269.         drives.sort()
  270.         choice_list = []
  271.         if not devices:
  272.             tmp_drives = GLIStorageDevice.detect_devices()
  273.             tmp_drives.sort()
  274.             for drive in tmp_drives:
  275.                 devices[drive] = GLIStorageDevice.Device(drive)
  276.                 #if self.local_install:  #when uncommenting please indent the next line.
  277.                 devices[drive].set_partitions_from_disk()
  278.                 drives.append(drive)
  279.                 choice_list.append((drive, devices[drive].get_model()))
  280.         else:
  281.             for drive in drives:
  282.                 choice_list.append((drive, devices[drive].get_model()))
  283.         #choice_list.append(("Other", "Type your own drive name))  # I DONT THINK GLISD CAN DO NONEXISTANT DRIVES
  284.         while 1:
  285.             code, drive_to_partition = self._d.menu(_(u"Which drive would you like to partition?\n Info provided: Type, mkfs Options, Mountpoint, Mountopts, Size in MB"), choices=choice_list, cancel=_(u"Save and Continue"))
  286.             if code != self._DLG_OK: break
  287.             while 1:
  288.                 partitions = devices[drive_to_partition].get_partitions()
  289.                 partlist = devices[drive_to_partition].get_ordered_partition_list()
  290.                 tmpparts = devices[drive_to_partition].get_partitions()
  291.                 partsmenu = []
  292.                 for part in partlist:
  293.                     tmppart = tmpparts[part]
  294.                     entry = ""
  295.                     if tmppart.get_type() == "free":
  296.                         #partschoice = "New"
  297.                         entry = _(u" - Unallocated space (")
  298.                         if tmppart.is_logical():
  299.                             entry += _(u"logical, ")
  300.                         entry += str(tmppart.get_mb()) + "MB)"
  301.                     elif tmppart.get_type() == "extended":
  302.                         entry = str(int(tmppart.get_minor()))
  303.                         entry += _(u" - Extended Partition (") + str(tmppart.get_mb()) + "MB)"
  304.                     else:
  305.                         entry = str(int(tmppart.get_minor())) + " - "
  306.                         # Type: " + tmppart.get_type() + ", Mountpoint: " + tmppart.get_mountpoint() + ", Mountopts: " + tmppart.get_mountopts() + "("
  307.                         if tmppart.is_logical():
  308.                             entry += _(u"Logical (")
  309.                         else:
  310.                             entry += _(u"Primary (")
  311.                         entry += tmppart.get_type() + ", "
  312.                         entry += (tmppart.get_mkfsopts() or "none") + ", "
  313.                         entry += (tmppart.get_mountpoint() or "none") + ", "
  314.                         entry += (tmppart.get_mountopts() or "none") + ", "
  315.                         entry += str(tmppart.get_mb()) + "MB)"
  316.                     partsmenu.append(entry)
  317.                 #Add recommended partitioning option and clear option
  318.                 partsmenu.append(_(u"Set Recommended Layout (needs 4GB+)"))
  319.                 partsmenu.append(_(u"Clear Partitions On This Drive."))
  320.                 code, part_to_edit = self._d.menu(_(u"Select a partition or unallocated space to edit\nKey: Minor, Pri/Ext, Filesystem, MkfsOpts, Mountpoint, MountOpts, Size."), width=70, choices=self._dmenu_list_to_choices(partsmenu), cancel=_(u"Back"))
  321.                 if code != self._DLG_OK: break
  322.                 partmenuchoice = partsmenu[int(part_to_edit)-1]
  323.                 #Check for recommended and clear here before setting the tmppart
  324.                 if partmenuchoice == _(u"Set Recommended Layout (needs 4GB+)"):
  325.                     try:
  326.                         devices[drive_to_partition].do_recommended()
  327.                     except GLIException, error:
  328.                         self._d.msgbox(_(u"The recommended layout could NOT be set.  The following message was received:")+error.get_error_msg(), width=70, height=15)
  329.                     continue
  330.                 if partmenuchoice == _(u"Clear Partitions On This Drive."):
  331.                     try:
  332.                         devices[drive_to_partition].clear_partitions()
  333.                         self._d.msgbox(_(u"Partition table cleared successfully"))
  334.                     except:
  335.                         self._d.msgbox(_(u"ERROR: could not clear the partition table!"))
  336.                     continue
  337.                 #all other cases (partitions)
  338.                 part_to_edit = partlist[int(part_to_edit)-1]
  339.                 tmppart = tmpparts[part_to_edit]
  340.                 if tmppart.get_type() == "free":
  341.                     # partition size first
  342.                     free_mb = tmppart.get_mb()
  343.                     code, new_mb = self._d.inputbox(_(u"Enter the size of the new partition in MB (max %s MB).  If creating an extended partition input its entire size (not just the first logical size):") % str(free_mb), init=str(free_mb))
  344.                     if code != self._DLG_OK: continue
  345.                     if int(new_mb) > free_mb:
  346.                         self._d.msgbox(_(u"The size you entered (%s MB) is larger than the maximum of %s MB") % (new_mb, str(free_mb)))
  347.                         continue
  348.                     # partition type
  349.                     part_types = [("ext2", _(u"Old, stable, but no journaling")),
  350.                     ("ext3", _(u"ext2 with journaling and b-tree indexing (RECOMMENDED)")),
  351.                     ("linux-swap", _(u"Swap partition for memory overhead")),
  352.                     ("fat32", _(u"Windows filesystem format used in Win9X and XP")),
  353.                     ("ntfs", _(u"Windows filesystem format used in Win2K and NT")),
  354.                     ("jfs", _(u"IBM's journaling filesystem.  stability unknown.")),
  355.                     ("xfs", _(u"Don't use this unless you know you need it.")),
  356.                     ("reiserfs", _(u"B*-tree based filesystem. great performance. Only V3 supported.")),
  357.                     ("extended", _(u"Create an extended partition containing other logical partitions")),
  358.                     ("Other", _(u"Something else we probably don't support."))]
  359.                     code, type = self._d.menu(_(u"Choose the filesystem type for this new partition."), height=20, width=77, choices=part_types)
  360.                     if code != self._DLG_OK: continue
  361.                                         
  362.                     # 'other' partition type
  363.                     if type == "Other":
  364.                         code, type = self._d.inputbox(_(u"Please enter the new partition's type:"))
  365.                     if code != self._DLG_OK: continue
  366.                     
  367.                     # now add it to the data structure
  368.                     devices[drive_to_partition].add_partition(part_to_edit, int(new_mb), 0, 0, type)
  369.                 else:
  370.                     while 1:
  371.                         tmppart = tmpparts[part_to_edit]
  372.                         tmptitle = drive_to_partition + str(part_to_edit) + " - "
  373.                         if tmppart.is_logical():
  374.                             tmptitle += _(u"Logical (")
  375.                         else:
  376.                             tmptitle += _(u"Primary (")
  377.                         tmptitle += tmppart.get_type() + ", "
  378.                         tmptitle += (tmppart.get_mkfsopts() or "none") + ", "
  379.                         tmptitle += (tmppart.get_mountpoint() or "none") + ", "
  380.                         tmptitle += (tmppart.get_mountopts() or "none") + ", "
  381.                         tmptitle += str(tmppart.get_mb()) + "MB)"
  382.                         menulist = [_(u"Delete"), _(u"Mount Point"), _(u"Mount Options"), _(u"Format"), _(u"Extra mkfs.* Parameters")]
  383.                         code, part_action = self._d.menu(tmptitle, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
  384.                         if code != self._DLG_OK: break
  385.                         part_action = menulist[int(part_action)-1]
  386.                         if part_action == _(u"Delete"):
  387.                             answer = (self._d.yesno(_(u"Are you sure you want to delete the partition ") + drive_to_partition + str(part_to_edit) + "?") == self._DLG_YES)
  388.                             if answer == True:
  389.                                 tmpdev = tmppart.get_device()
  390.                                 tmpdev.remove_partition(part_to_edit)
  391.                                 break
  392.                         elif part_action == _(u"Mount Point"):
  393.                             mountpoint_menu = ["/","/boot","/etc","/home","/lib","/mnt","/mnt/windows","/opt","/root","/usr","/usr/local","/usr/portage","/var",_(u"Other")]
  394.                             code, mountpt = self._d.menu(_(u"Choose a mountpoint from the list or choose Other to type your own for partition ")+str(part_to_edit)+_(u".  It is currently set to:")+tmppart.get_mountpoint(), choices=self._dmenu_list_to_choices(mountpoint_menu)) #may have to make that an integer
  395.                             if code == self._DLG_OK:
  396.                                 mountpt = mountpoint_menu[int(mountpt)-1]
  397.                                 if mountpt == _(u"Other"):
  398.                                     code, mountpt = self._d.inputbox(_(u"Enter a mountpoint for partition ") + str(part_to_edit), init=tmppart.get_mountpoint())
  399.                             try: tmppart.set_mountpoint(mountpt)
  400.                             except: self._d.msgbox(_(u"ERROR! Could not set mountpoint!"))
  401.                         elif part_action == _(u"Mount Options"):
  402.                             code, answer = self._d.inputbox(_(u"Enter your mount options for partition ") + str(part_to_edit), init=(tmppart.get_mountopts() or "defaults"))
  403.                             if code == self._DLG_OK: tmppart.set_mountopts(answer)
  404.                         elif part_action == _(u"Format"):
  405.                             #Change the Yes/No buttons back.
  406.                             self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  407.                             self._d.add_persistent_args(["--no-label", _(u"No")])
  408.                             code = self._d.yesno(_(u"Do you want to format this partition?"))
  409.                             if code == self._DLG_YES: 
  410.                                 tmppart.set_format(True)
  411.                             else:
  412.                                 tmppart.set_format(False)
  413.                         elif part_action == _(u"Extra mkfs.* Parameters"):
  414.                             new_mkfsopts = tmppart.get_mkfsopts()
  415.                             # extra mkfs options
  416.                             if tmppart.get_type() != "extended":
  417.                                 code, new_mkfsopts = self._d.inputbox(_(u"Extra mkfs.* Parameters"), init=new_mkfsopts)
  418.                                 if code == self._DLG_OK: tmppart.set_mkfsopts(new_mkfsopts)                            
  419.         try:                                        
  420.             self._install_profile.set_partition_tables(devices)
  421.         except:
  422.             self._d.msgbox(_(u"ERROR:  The partition tables could not be set correctly!"))
  423.  
  424.     def set_network_mounts(self):
  425.     # This is where any NFS mounts will be specified
  426.         network_mounts = copy.deepcopy(self._install_profile.get_network_mounts())
  427.         while 1:
  428.             menulist = []
  429.             for mount in network_mounts:
  430.                 menulist.append(mount['host'] + ":" + mount['export'])
  431.             menulist.append(_(u"Add a new network mount"))
  432.             choices = self._dmenu_list_to_choices(menulist)
  433.             code, menuitemidx = self._d.menu(_(u"If you have any network shares you would like to mount during the install and for your new system, define them here. Select a network mount to edit or add a new mount.  Currently GLI only supports NFS mounts."), choices=choices, cancel=_(u"Save and Continue"), height=18)
  434.             if code == self._DLG_CANCEL:
  435.                 try:
  436.                     self._install_profile.set_network_mounts(network_mounts)
  437.                 except:
  438.                     self._d.msgbox(_(u"ERROR: Could net set network mounts!"))
  439.                 break
  440.             menuitem = menulist[int(menuitemidx)-1]
  441.             if menuitem == _(u"Add a new network mount"):
  442.                 code, nfsmount = self._d.inputbox(_(u"Enter NFS mount or just enter the IP/hostname to search for available mounts"), height=13, width=50)
  443.                 if code != self._DLG_OK: 
  444.                     continue
  445.                 if not GLIUtility.is_nfs(nfsmount):
  446.                     if GLIUtility.is_ip(nfsmount) or GLIUtility.is_hostname(nfsmount):
  447.                         status, remotemounts = GLIUtility.spawn("/usr/sbin/showmount -e " + nfsmount + " 2>&1 | egrep '^/' | cut -d ' ' -f 1 && echo", return_output=True)
  448.                         remotemounts = remotemounts.strip().split("\n")
  449.                         if (not GLIUtility.exitsuccess(status)) or (not len(remotemounts)) or not remotemounts[0]:
  450.                             self._d.msgbox(_(u"No NFS exports were detected on ") + nfsmount)
  451.                             continue
  452.                         code, nfsmount2 = self._d.menu(_(u"Select a NFS export"), choices=self._dmenu_list_to_choices(remotemounts), cancel=_(u"Back"))
  453.                         if code != self._DLG_OK: 
  454.                             continue
  455.                         nfsmount2 = remotemounts[int(nfsmount2)-1]
  456.                     else:
  457.                         self._d.msgbox(_(u"The address you entered, %s, is not a valid IP or hostname.  Please try again.") % nfsmount)
  458.                         continue
  459.                 else:
  460.                     colon_location = nfsmount.find(':')
  461.                     menuitem = nfsmount
  462.                     nfsmount = menuitem[:colon_location]
  463.                     nfsmount2 = menuitem[colon_location+1:]
  464.                 for mount in network_mounts:
  465.                     if nfsmount == mount['host'] and nfsmount2 == mount['export']:
  466.                         self._d.msgbox(_(u"There is already an entry for ") + nfsmount + ":" + nfsmount2 + ".")
  467.                         nfsmount = None
  468.                         break
  469.                 if nfsmount == None: 
  470.                     continue
  471.                 network_mounts.append({'export': nfsmount2, 'host': nfsmount, 'mountopts': '', 'mountpoint': '', 'type': 'nfs'})
  472.                 menuitem = nfsmount + ":" + nfsmount2
  473.                 menuitemidx = len(network_mounts)
  474.  
  475.             if menuitem.find(':') != -1:
  476.                 colon_location = menuitem.find(':')
  477.                 tmpmount = network_mounts[int(menuitemidx)-1]
  478.                 code, mountpoint = self._d.inputbox(_(u"Enter a mountpoint"), init=tmpmount['mountpoint'])
  479.                 if code == self._DLG_OK: 
  480.                     tmpmount['mountpoint'] = mountpoint
  481.                 code, mountopts = self._d.inputbox(_(u"Enter mount options"), init=tmpmount['mountopts'])
  482.                 if code == self._DLG_OK: 
  483.                     tmpmount['mountopts'] = mountopts
  484.                 network_mounts[int(menuitemidx)-1] = tmpmount
  485.  
  486.     def set_install_stage(self):
  487.     # The install stage and stage tarball will be selected here
  488.         install_stages = (("1",_(u"Stage1 is used when you want to bootstrap&build from scratch.")),
  489.                         ("2",_(u"Stage2 is used for building from a bootstrapped semi-compiled state.")),
  490.                         ("3",_(u"Stage3 is a basic system that has been built for you (no compiling).")), 
  491.                         ("3+GRP", _(u"A Stage3 install but using binaries from the LiveCD when able.")))
  492.         code, install_stage = self._d.menu(_(u"Which stage do you want to start at?"), choices=install_stages, cancel=_(u"Back"), width=78)
  493.         stage3warning = ""
  494.         if code == self._DLG_OK:
  495.             if install_stage == "3+GRP":
  496.                 stage3warning = "\nWARNING: Since you are doing a GRP install it is HIGHLY recommended you choose Create from CD to avoid a potentially broken installation."
  497.                 try:
  498.                     self._install_profile.set_grp_install(None, True, None)
  499.                 except:
  500.                     self._d.msgbox(_(u"ERROR! Could not set install stage!"))
  501.                 install_stage = "3"
  502.             try:            
  503.                 self._install_profile.set_install_stage(None, install_stage, None)
  504.             except:
  505.                 self._d.msgbox(_(u"ERROR! Could not set install stage!"))
  506.         has_systempkgs = GLIUtility.is_file("/usr/livecd/systempkgs.txt")
  507.         if install_stage == "3" and has_systempkgs:
  508.             #Change the Yes/No buttons to new labels for this question.
  509.             self._d.add_persistent_args(["--yes-label", _(u"Create from CD")])
  510.             self._d.add_persistent_args(["--no-label", _(u"Specify URI")])
  511.             if self._d.yesno(_(u"Do you want to generate a stage3 on the fly using the files on the LiveCD (fastest) or do you want to grab your stage tarball from the Internet?"+stage3warning), width=55) == self._DLG_YES:
  512.                 #Generate on the FLY                
  513.                 try:
  514.                     self._install_profile.set_dynamic_stage3(None, True, None)
  515.                 except:
  516.                     self._d.msgbox(_(u"ERROR: Could not set the stage tarball URI!"))
  517.                 return
  518.         #Specify URI
  519.         #subarches = { 'x86': ("x86", "i686", "pentium3", "pentium4", "athlon-xp"), 'hppa': ("hppa1.1", "hppa2.0"), 'ppc': ("g3", "g4", "g5", "ppc"), 'sparc': ("sparc32", "sparc64")}
  520.         type_it_in = False
  521.         stage_tarball = ""
  522.         if GLIUtility.ping("www.gentoo.org"):  #Test for network connectivity
  523.             mirrors = GLIUtility.list_mirrors()
  524.             mirrornames = []
  525.             mirrorurls = []
  526.             for item in mirrors:
  527.                 mirrornames.append(item[1])
  528.                 mirrorurls.append(item[0])
  529.             code, mirror = self._d.menu(_(u"Select a mirror to grab the tarball from or select Cancel to enter an URI manually."), choices=self._dmenu_list_to_choices(mirrornames), width=77, height=20)
  530.             if code != self._DLG_OK:
  531.                 type_it_in = True
  532.             else:
  533.                 mirror = mirrorurls[int(mirror)-1]
  534.                 arch = self._client_profile.get_architecture_template()
  535.                 subarches = GLIUtility.list_subarch_from_mirror(mirror,arch)
  536.                 if subarches:
  537.                     code, subarch = self._d.menu(_(u"Select the sub-architecture that most closely matches your system (this changes the amount of optimization):"), choices=self._dmenu_list_to_choices(subarches))
  538.                     if code != self._DLG_OK:
  539.                         type_it_in = True
  540.                     else:
  541.                         subarch = subarches[int(subarch)-1]    
  542.                 else:
  543.                     subarch = ""
  544.                 if not type_it_in:
  545.                     tarballs = GLIUtility.list_stage_tarballs_from_mirror(mirror, arch, subarch)
  546.                     code, stage_tarball = self._d.menu(_(u"Select your desired stage tarball:"), choices=self._dmenu_list_to_choices(tarballs))
  547.                     if (code != self._DLG_OK):
  548.                         type_it_in = True
  549.                     else:
  550.                         stage_tarball = mirror + "/releases/" + arch + "/current/stages/" + subarch + tarballs[int(stage_tarball)-1]
  551.         #get portageq envvar value of cflags and look for x86, i686,etc.
  552.             #URL SYNTAX
  553.             #http://gentoo.osuosl.org/releases/ARCHITECTURE/current/stages/SUB-ARCH/
  554.         else:
  555.             type_it_in = True
  556.         if type_it_in:
  557.             code, stage_tarball = self._d.inputbox(_(u"Specify the stage tarball URI or local file:"), init=self._install_profile.get_stage_tarball_uri())
  558.             if code != self._DLG_OK:
  559.                 return
  560.         #If Doing a local install, check for valid file:/// uri
  561.         if stage_tarball:
  562.             if not GLIUtility.is_uri(stage_tarball, checklocal=self.local_install):
  563.                 self._d.msgbox(_(u"The specified URI is invalid.  It was not saved.  Please go back and try again."));
  564.             else: self._install_profile.set_stage_tarball_uri(None, stage_tarball, None)
  565.         else: self._d.msgbox(_(u"No URI was specified!"))
  566.             #if d.yesno("The specified URI is invalid. Use it anyway?") == DLG_YES: install_profile.set_stage_tarball_uri(None, stage_tarball, None)
  567.     
  568.     def set_portage_tree(self):
  569.     # This section will ask whether to sync the tree, whether to use a snapshot, etc.
  570.         if self._install_profile.get_dynamic_stage3():  #special case
  571.             try:
  572.                 self._install_profile.set_portage_tree_sync_type(None,"snapshot", None)
  573.                 cd_snapshot_uri = GLIUtility.get_cd_snapshot_uri()
  574.                 self._install_profile.set_portage_tree_snapshot_uri(None, cd_snapshot_uri, None)
  575.             except:
  576.                 self._d.msgbox(_(u"ERROR! Could not set the portage cd snapshot URI!"))
  577.             return
  578.             
  579.         #Normal case
  580.         menulist = [("Sync", _(u"Normal. Use emerge sync RECOMMENDED!")),
  581.         ("Webrsync", _(u"HTTP daily snapshot. Use when rsync is firewalled.")),
  582.         ("Snapshot", _(u"Use a portage snapshot, either a local file or a URL")),
  583.         ("None", _(u"Extra cases such as if /usr/portage is an NFS mount"))]
  584.         code, portage_tree_sync = self._d.menu(_(u"Which method do you want to use to sync the portage tree for the installation?  If choosing a snapshot you will need to provide the URI for the snapshot if it is not on the livecd."),width=75, height=17, choices=menulist)
  585.         if code != self._DLG_OK: 
  586.             return
  587.         self._install_profile.set_portage_tree_sync_type(None, portage_tree_sync.lower(), None)
  588.         if portage_tree_sync == "Snapshot":
  589.             if self._install_profile.get_portage_tree_snapshot_uri():
  590.                 initval = self._install_profile.get_portage_tree_snapshot_uri()
  591.             else:
  592.                 initval = GLIUtility.get_cd_snapshot_uri()
  593.             code, snapshot = self._d.inputbox(_(u"Enter portage tree snapshot URI"), init=initval)
  594.             if code == self._DLG_OK:
  595.                 if snapshot: 
  596.                     if not GLIUtility.is_uri(snapshot, checklocal=self.local_install):
  597.                         self._d.msgbox(_(u"The specified URI is invalid.  It was not saved.  Please go back and try again."))
  598.                     else: 
  599.                         self._install_profile.set_portage_tree_snapshot_uri(None, snapshot, None)
  600.             
  601.                 else: 
  602.                     self._d.msgbox(_(u"No URI was specified! Returning to default emerge sync."))
  603.             #if d.yesno("The specified URI is invalid. Use it anyway?") == DLG_YES: install_profile.set_stage_tarball_uri(None, stage_tarball, None)
  604.  
  605.  
  606.  
  607.     def set_make_conf(self):
  608.     # This section will be for setting things like CFLAGS, ACCEPT_KEYWORDS, and USE
  609.         #special case for dynamic stage3
  610.         if self._install_profile.get_dynamic_stage3() and not self.advanced_mode:
  611.             return
  612.         
  613.         etc_files = self._install_profile.get_etc_files()
  614.         if etc_files.has_key("make.conf"):
  615.             make_conf = etc_files['make.conf']
  616.         else:
  617.             make_conf = {}
  618.         
  619.         self._d.msgbox(_(u"""The installer will now gather information regarding the contents of /etc/make.conf
  620. One of the unique (and best) features of Gentoo is the ability to
  621. define flags (called USE flags) that define what components are 
  622. compiled into applications.  For example, you can enable the alsa
  623. flag and programs that have alsa capability will use it.  
  624. The result is a finely tuned OS with no unnecessary components to
  625. slow you down.
  626. The installer divides USE flag selection into two screens, one for
  627. global USE flags and one for local flags specific to each program.
  628. Please be patient while the screens load. It may take awhile."""), width=73, height=16)
  629.                     
  630.         #First set the USE flags, this is a biggie.
  631.         if make_conf.has_key("USE"): 
  632.             system_use_flags = make_conf["USE"]
  633.         else:  #not a preloaded config.  this is the NORMAL case.
  634.             system_use_flags = GLIUtility.spawn("portageq envvar USE", return_output=True)[1].strip().split()
  635.         use_flags = []
  636.         use_local_flags = []
  637.         use_desc = GLIUtility.get_global_use_flags()
  638.         use_local_desc = GLIUtility.get_local_use_flags()
  639.         
  640.         #populate the choices list
  641.         sorted_use = use_desc.keys()
  642.         sorted_use.sort()
  643.         for flagname in sorted_use:
  644.             use_flags.append((flagname, use_desc[flagname], int(flagname in system_use_flags)))
  645.         #present the menu
  646.         code, use_flags = self._d.checklist(_(u"Choose which *global* USE flags you want on the new system"), height=25, width=80,list_height=17, choices=use_flags)    
  647.         
  648.         #populate the chocies list
  649.         sorted_use = use_local_desc.keys()
  650.         sorted_use.sort()
  651.         for flagname in sorted_use:
  652.             use_local_flags.append((flagname, use_local_desc[flagname], int(flagname in system_use_flags)))
  653.         #present the menu
  654.         code, use_local_flags = self._d.checklist(_(u"Choose which *local* USE flags you want on the new system"), height=25, width=80,list_height=17, choices=use_local_flags)    
  655.         temp_use = "-* "
  656.         for flag in use_flags:
  657.             temp_use += flag + " "
  658.         for flag in use_local_flags:
  659.             temp_use += flag + " "
  660.         make_conf["USE"] = temp_use
  661.         
  662.         if not self._install_profile.get_dynamic_stage3() and self.advanced_mode:
  663.             #Second, set the ACCEPT_KEYWORDS
  664.             #Change the Yes/No buttons to new labels for this question.
  665.             self._d.add_persistent_args(["--yes-label", _(u"Stable")])
  666.             self._d.add_persistent_args(["--no-label", _(u"Unstable")])
  667.             if self._d.yesno(_(u"Do you want to run the normal stable portage tree, or the bleeding edge unstable (i.e. ACCEPT_KEYWORDS=arch)?  If unsure select stable.  Stable is required for GRP installs."), height=12, width=55) == self._DLG_YES:
  668.                 #Stable
  669.                 make_conf["ACCEPT_KEYWORDS"] = ""
  670.             else:  #Unstable
  671.                 make_conf["ACCEPT_KEYWORDS"] = "~" + self._client_profile.get_architecture_template()
  672.         #Third, misc. stuff.
  673.         while self.advanced_mode:
  674.             menulist = [("CFLAGS",_(u"Edit your C Flags and Optimization level")),
  675.             ("CHOST", _(u"Change the Host Setting")),
  676.             ("MAKEOPTS", _(u"Specify number of parallel makes (-j) to perform.")),
  677.             ("FEATURES", _(u"Change portage functionality settings. (distcc/ccache)")),
  678.             ("GENTOO_MIRRORS", _(u"Specify mirrors to use for source retrieval.")),
  679.             ("SYNC", _(u"Specify server used by rsync to sync the portage tree.")),
  680.             (_(u"Other"), _(u"Specify your own variable and value."))]
  681.             if self._install_profile.get_dynamic_stage3():  #SPECIAL LIST WITHOUT CHOST
  682.                 menulist = [("CFLAGS",_(u"Edit your C Flags and Optimization level")),
  683.                     ("MAKEOPTS", _(u"Specify number of parallel makes (-j) to perform.")),
  684.                     ("FEATURES", _(u"Change portage functionality settings. (distcc/ccache)")),
  685.                     ("GENTOO_MIRRORS", _(u"Specify mirrors to use for source retrieval.")),
  686.                     ("SYNC", _(u"Specify server used by rsync to sync the portage tree.")),
  687.                     (_(u"Other"), _(u"Specify your own variable and value."))]
  688.             code, menuitem = self._d.menu(_(u"For experienced users, the following /etc/make.conf variables can also be defined.  Choose a variable to edit or Done to continue."), choices=menulist, cancel=_(u"Done"), width=77)
  689.             if code != self._DLG_OK: 
  690.                 break
  691.             if menuitem == _(u"Other"):
  692.                 code,menuitem = self._d.inputbox(_(u"Enter the variable name: "))
  693.                 if code != self._DLG_OK:
  694.                     continue
  695.             oldval = ""
  696.             if make_conf.has_key(menuitem): 
  697.                 oldval = make_conf[menuitem]
  698.                 if oldval:
  699.                     code, newval = self._d.inputbox(_(u"Enter new value for ") + menuitem, init=oldval)
  700.                     if code == self._DLG_OK:
  701.                         make_conf[menuitem] = newval
  702.                     continue
  703.             #SPECIAL CASES here with their own menus.
  704.             if menuitem == "CFLAGS":
  705.                 if not make_conf.has_key("CFLAGS"):
  706.                     try:
  707.                         cflags = GLIUtility.get_value_from_config("/etc/make.conf","CFLAGS")
  708.                     except:
  709.                         cflags = ""
  710.                 else:
  711.                     cflags = make_conf['CFLAGS']
  712.                 while 1:
  713.                     choices_list = [
  714.                     ("CLEAR",_(u"Erase the current value and start over.")),
  715.                     ("-mcpu",_(u"Add a CPU optimization (deprecated in GCC 3.4)")),
  716.                     ("-mtune",_(u"Add a CPU optimization (GCC 3.4+)")),
  717.                     ("-march",_(u"Add an Architecture optimization")),
  718.                     ("-O",_(u"Add optimization level (please do NOT go over 2)")),
  719.                     ("-fomit-frame-pointer",_(u"For advanced users only.")),
  720.                     ("-pipe",_(u"Common additional flag")),
  721.                     (_(u"Manual"),_(u"Specify your CFLAGS manually"))
  722.                     ]
  723.                     code, choice = self._d.menu(_(u"Choose a flag to add to the CFLAGS variable or Done to go back.  The current value is: ")+ cflags, choices=choices_list, cancel=_(u"Done"), width=70)
  724.                     if code != self._DLG_OK:
  725.                         break
  726.                     if choice == "CLEAR":
  727.                         cflags = ""
  728.                     elif choice == _(u"Manual"):
  729.                         code, cflags = self._d.inputbox(_(u"Enter new value for ") + menuitem)
  730.                         break
  731.                     elif choice in ["-fomit-frame-pointer","-pipe"]:
  732.                         cflags += " "+choice
  733.                     else:
  734.                         code, newval = self._d.inputbox(_(u"Enter the new value for %s (value only):") % choice)
  735.                         if code != self._DLG_OK or not newval:
  736.                             continue
  737.                         if choice == "-O":
  738.                             cflags += " "+choice+newval
  739.                         else:
  740.                             cflags += " "+choice+"="+newval
  741.                 if cflags:
  742.                     make_conf['CFLAGS'] = cflags
  743.             elif menuitem == "CHOST":
  744.                 choices_list = GLIUtility.get_chosts(self._client_profile.get_architecture_template())
  745.                 code, chost = self._d.menu(_(u"Choose from the available CHOSTs for your architecture."), choices=self._dmenu_list_to_choices(choices_list), width=77)
  746.                 if code != self._DLG_OK: 
  747.                     continue
  748.                 chost = choices_list[int(chost)-1]
  749.                 make_conf['CHOST'] = chost
  750.             elif menuitem == "MAKEOPTS":
  751.                 makeopt_string = _(u"Presently the only use is for specifying the number of parallel makes (-j) to perform. The suggested number for parallel makes is CPUs+1.  Enter the NUMBER ONLY:")
  752.                 code, newval = self._d.inputbox(makeopt_string, width=60)
  753.                 if code != self._DLG_OK:
  754.                     continue
  755.                 make_conf['MAKEOPTS'] = "-j "+str(newval)
  756.             elif menuitem == "FEATURES":
  757.                 choices_list = [("sandbox",_(u"enables sandboxing when running emerge and ebuild."),0),
  758.                 ("ccache",_(u"enables ccache support via CC."),0),
  759.                 ("distcc",_(u"enables distcc support via CC."),0),
  760.                 ("distlocks",_(u"enables distfiles locking using fcntl or hardlinks."),0),
  761.                 ("buildpkg",_(u"create binaries of all packages emerged"),0),
  762.                 (_(u"Other"),_(u"Input your list of FEATURES manually."),0)    ]
  763.                 features_string = _(u"FEATURES are settings that affect the functionality of portage. Most of these settings are for developer use, but some are available to non-developers as well.")
  764.                 code, choices = self._d.checklist(features_string, choices=choices_list, width=75)
  765.                 if code != self._DLG_OK:
  766.                     continue
  767.                 if _(u"Other") in choices:
  768.                     code, features = self._d.inputbox(_(u"Enter the value of FEATURES: "))
  769.                 elif choices:
  770.                     features = string.join(choices, ' ')
  771.                 else:
  772.                     features = ""
  773.                 if features:
  774.                     make_conf['FEATURES'] = features
  775.             else:
  776.                 code, newval = self._d.inputbox(_(u"Enter new value for ") + menuitem)
  777.                 if code == self._DLG_OK and newval:
  778.                     make_conf[menuitem] = newval
  779.  
  780.         try:
  781.             if make_conf:
  782.                 etc_files['make.conf'] = make_conf
  783.                 self._install_profile.set_etc_files(etc_files)
  784.         except:
  785.             self._d.msgbox(_(u"ERROR! Could not set the make_conf correctly!"))
  786.  
  787.     def set_distcc(self):
  788.         #Change the Yes/No buttons for this question.
  789.         self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  790.         self._d.add_persistent_args(["--no-label", _(u"No")])
  791.         if self._d.yesno(_(u"Do you want to use distcc to compile your extra packages during the install and for future compilations as well?"), height=12, width=60) == self._DLG_YES:
  792.             #Add distcc to the services list.
  793.             if self._install_profile.get_services():
  794.                 services = self._install_profile.get_services()
  795.                 if isinstance(services, str):
  796.                     services = services.split(',')
  797.             else:
  798.                 services = []
  799.             if not "distccd" in services:
  800.                 services.append("distccd")
  801.             try:
  802.                 services = string.join(services, ',')
  803.                 if services:
  804.                     self._install_profile.set_services(None, services, None)
  805.             except:
  806.                 self._d.msgbox(_(u"ERROR! Could not set the services list."))
  807.                 return
  808.             #Set the distcc flag to emerge earlier than other packages.
  809.             try:
  810.                 self._install_profile.set_install_distcc(None, True, None)
  811.             except:
  812.                 self._d.msgbox(_(u"ERROR! Could not set the install distcc flag!"))
  813.                 return
  814.  
  815.             #Add distcc to the FEATURES in make.conf and add DISTCC_HOSTS too.
  816.             etc_files = self._install_profile.get_etc_files()
  817.             #load up the make.conf
  818.             if etc_files.has_key("make.conf"):
  819.                 make_conf = etc_files['make.conf']
  820.             else:
  821.                 make_conf = {}
  822.             #Check for FEATURES and add if not already there.
  823.             if make_conf.has_key("FEATURES"):
  824.                 if not "distcc" in make_conf['FEATURES']:
  825.                     make_conf['FEATURES'] += " distcc"
  826.             else:
  827.                 make_conf['FEATURES'] = "distcc"
  828.             #Now while still working in make.conf, figure out what HOSTS to set.
  829.             if make_conf.has_key("DISTCC_HOSTS"):
  830.                 initval = make_conf['DISTCC_HOSTS']
  831.             else:
  832.                 initval = "localhost "
  833.             distcc_string = _(u"Enter the hosts to be used by distcc for compilation:\nExample: localhost    192.168.0.2     192.168.0.3:4000/10")
  834.             code, hosts = self._d.inputbox(distcc_string, width=75, init=initval)
  835.             if code != self._DLG_OK:
  836.                 hosts = initval
  837.             make_conf['DISTCC_HOSTS'] = hosts
  838.             try:
  839.                 etc_files['make.conf'] = make_conf
  840.                 self._install_profile.set_etc_files(etc_files)
  841.             except:
  842.                 self._d.msgbox(_(u"ERROR! Could not set the make_conf correctly!"))    
  843.  
  844.     def set_etc_portage(self):
  845.     #This section will be for editing the /etc/portage/* files and other /etc/* files.  This should be for advanced users only.
  846.         etc_files = self._install_profile.get_etc_files()
  847.         while self.advanced_mode:
  848.             
  849.             menulist = [("portage/package.mask",_(u"A list of DEPEND atoms to mask.")),
  850.             ("portage/package.unmask",_(u"A list of packages to unmask.")),
  851.             ("portage/package.keywords",_(u"Per-package KEYWORDS (like ACCEPT_KEYWORDS).")),
  852.             ("portage/package.use",_(u"Per-package USE flags.")),
  853.             (_(u"Other"),_(u"Type your own name of a file to edit in /etc/"))]
  854.             code, menuitem = self._d.menu(_(u"For experienced users, the following /etc/* variables can also be defined.  Choose a variable to edit or Done to continue."), choices=menulist, cancel=_(u"Done"), width=77)
  855.             if code != self._DLG_OK: 
  856.                 break  #get out of the while loop. then save and continue
  857.             
  858.             if menuitem == _(u"Other"):
  859.                 code, menuitem = self._d.inputbox(_(u"Enter the name of the /etc/ file you would like to edit (DO NOT type /etc/)"))
  860.                 if code != self._DLG_OK:
  861.                     return
  862.             oldval = ""
  863.             if etc_files.has_key(menuitem): 
  864.                 oldval = etc_files[menuitem]
  865.                 
  866.             code, newval = self._d.inputbox(_(u"Enter new contents (use \\n for newline) of ") + menuitem, init=oldval)
  867.             if code == self._DLG_OK:
  868.                 etc_files[menuitem] = []
  869.                 etc_files[menuitem].append(newval)
  870.         try:
  871.             self._install_profile.set_etc_files(etc_files)
  872.         except:
  873.             self._d.msgbox(_(u"ERROR! Could not set etc/portage/* correctly!"))
  874.  
  875.         
  876.  
  877.     def set_kernel(self):
  878.     # This section will be for choosing kernel sources, choosing (and specifying) a custom config or genkernel, modules to load at startup, etc.
  879.         kernel_sources = [("livecd-kernel", _(u"Copy over the current running kernel (fastest)")),
  880.         ("vanilla-sources", _(u"The Unaltered Linux Kernel ver 2.6+ (safest)")),
  881.         ("gentoo-sources", _(u"Gentoo's optimized 2.6+ kernel. (less safe)")),
  882.         ("hardened-sources", _(u"Hardened sources for the 2.6 kernel tree")),
  883.         ("grsec-sources",_(u"Vanilla sources with grsecurity patches")),
  884.         (_(u"Other"), _(u"Choose one of the other sources available."))]
  885.         code, menuitem = self._d.menu(_(u"Choose which kernel sources to use for your system.  If using a previously-made kernel configuration, make sure the sources match the kernel used to create the configuration."), choices=kernel_sources, width=77, height=17)
  886.         if code != self._DLG_OK: 
  887.             return
  888.         if menuitem == _(u"Other"):
  889.             code, menuitem = self._d.inputbox(_(u"Please enter the desired kernel sources package name:"))
  890.             if code != self._DLG_OK: return
  891.         try:
  892.             self._install_profile.set_kernel_source_pkg(None, menuitem, None)
  893.         except:
  894.             self._d.msgbox(_(u"ERROR! Could not set the kernel source package!"))
  895.         if not menuitem == "livecd-kernel":
  896.             #Change the Yes/No buttons to new labels for this question.
  897.             self._d.add_persistent_args(["--yes-label", _(u"Genkernel")])
  898.             self._d.add_persistent_args(["--no-label", _(u"Traditional (requires a config!)")])
  899.             kernel_string1 = _(u"There are currently two ways the installer can compile a kernel for your new system.  You can either provide a previously-made kernel configuration file and use the traditional kernel-compiling procedure (no initrd) or have genkernel automatically create your kernel for you (with initrd).  \n\n If you do not have a previously-made kernel configuration, YOU MUST CHOOSE Genkernel.  Choose which method you want to use.")
  900.             if self._d.yesno(kernel_string1, width=76,height=13) == self._DLG_YES:   #Genkernel
  901.                 self._install_profile.set_kernel_build_method(None,"genkernel", None)
  902.                 if self.advanced_mode:
  903.                     #Change the Yes/No buttons back.
  904.                     self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  905.                     self._d.add_persistent_args(["--no-label", _(u"No")])
  906.                     if self._d.yesno(_(u"Do you want the bootsplash screen to show up on bootup?")) == self._DLG_YES:
  907.                         self._install_profile.set_kernel_bootsplash(None, True, None)
  908.                     else:
  909.                         self._install_profile.set_kernel_bootsplash(None, False, None)
  910.             else:     #Custom
  911.                 self._install_profile.set_kernel_build_method(None,"custom", None)
  912.             if self.advanced_mode:
  913.                 code, custom_kernel_uri = self._d.inputbox(_(u"If you have a custom kernel configuration, enter its location (otherwise just press Enter to continue):"), height=13, width=50)
  914.                 if code == self._DLG_OK: 
  915.                     if custom_kernel_uri: 
  916.                         if not GLIUtility.is_uri(custom_kernel_uri, checklocal=self.local_install):
  917.                             self._d.msgbox(_(u"The specified URI is invalid.  It was not saved.  Please go back and try again."))
  918.                         else: 
  919.                             try:
  920.                                 self._install_profile.set_kernel_config_uri(None, custom_kernel_uri, None)
  921.                             except:
  922.                                 self._d.msgbox(_(u"ERROR! Could not set the kernel config URI!"))
  923.                 #else: self._d.msgbox(_(u"No URI was specified!  Reverting to using genkernel"))
  924.                 
  925.     def set_boot_loader(self):
  926.         arch = self._client_profile.get_architecture_template()
  927.         parts = self._install_profile.get_partition_tables()
  928.         #Bootloader code yanked from the x86ArchTemplate
  929.         if self._install_profile.get_boot_device():
  930.             boot_device = self._install_profile.get_boot_device()
  931.         else:
  932.             boot_device = ""
  933.             foundboot = False
  934.             for device in parts:
  935.                 tmp_partitions = parts[device].get_install_profile_structure()
  936.                 for partition in tmp_partitions:
  937.                     mountpoint = tmp_partitions[partition]['mountpoint']
  938.                     if (mountpoint == "/boot"):
  939.                         foundboot = True
  940.                     if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
  941.                         boot_device = device
  942.  
  943.         arch_loaders = { 'x86': [
  944.             ("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED")),
  945.             ("lilo",_(u"LInux LOader, older, traditional.(detects windows partitions)"))],
  946.         'amd64': [
  947.             ("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED"))]} #FIXME ADD OTHER ARCHS
  948.         boot_loaders = arch_loaders[arch]
  949.         boot_loaders.append(("none", _(u"Do not install a bootloader.  (System may be unbootable!)")))
  950.         boot_string1 = _(u"To boot successfully into your new Linux system, a bootloader will be needed.  If you already have a bootloader you want to use you can select None here.  The bootloader choices available are dependent on what GLI supports and what architecture your system is.  Choose a bootloader")
  951.         code, menuitem = self._d.menu(boot_string1, choices=boot_loaders, height=16, width=74)
  952.         if code != self._DLG_OK: 
  953.             return
  954.         try:
  955.             self._install_profile.set_boot_loader_pkg(None, menuitem, None)
  956.         except:
  957.             self._d.msgbox(_(u"ERROR! Could not set boot loader pkg! ")+menuitem)
  958.         if menuitem != "none" and self.advanced_mode:
  959.             #Reset the Yes/No labels.
  960.             self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  961.             self._d.add_persistent_args(["--no-label",_(u"No")])
  962.             boot_string2 = _(u"Most bootloaders have the ability to install to either the Master Boot Record (MBR) or some other partition.  Most people will want their bootloader installed on the MBR for successful boots, but if you have special circumstances, you can have the bootloader installed to the /boot partition instead.  Do you want the boot loader installed in the MBR? (YES is RECOMMENDED)")
  963.             if self._d.yesno(boot_string2, height=13, width=55) == self._DLG_YES:
  964.                 self._install_profile.set_boot_loader_mbr(None, True, None)
  965.             else:
  966.                 self._install_profile.set_boot_loader_mbr(None, False, None)
  967.         if self._install_profile.get_boot_loader_mbr():  #If we're installing to MBR gotta check the device.
  968.             if self.advanced_mode or (boot_device[-1] != 'a'):
  969.                 #show the menu.
  970.                 boot_string3_std = _(u"Your boot device may not be correct.  It is currently set to %s, but this device may not be the first to boot.  Usually boot devices end in 'a' such as hda or sda.") % boot_device
  971.                 boot_string3 = _(u"  Please confirm your boot device by choosing it from the menu.")
  972.                 if not self.advanced_mode:
  973.                     boot_string3 = boot_string3_std + boot_string3
  974.                 #grab choies from the partiton list.
  975.                 boot_drive_choices = []
  976.                 for device in parts:
  977.                     boot_drive_choices.append(device)
  978.                 if not boot_drive_choices:
  979.                     self._d.msgbox(_(u"ERROR: No drives set up.  Please complete the Partitioning screen first!"))
  980.                     return
  981.                 code, boot_drive_choice = self._d.menu(boot_string3, choices=self._dmenu_list_to_choices(boot_drive_choices), height=16, width=70)
  982.                 if code != self._DLG_OK:
  983.                     return
  984.                 boot_drive_choice = boot_drive_choices[int(boot_drive_choice)-1]
  985.                 try:
  986.                     self._install_profile.set_boot_device(None,boot_drive_choice,None)
  987.                 except:
  988.                     self._d.msgbox(_(u"ERROR! Could not set the boot device!")+boot_drive_choice)
  989.         if self.advanced_mode:
  990.             code, bootloader_kernel_args = self._d.inputbox(_(u"If you have any additional optional arguments you want to pass to the kernel at boot, type them here or just press Enter to continue:"), height=12, width=55)
  991.             if code == self._DLG_OK:
  992.                 try:
  993.                     self._install_profile.set_bootloader_kernel_args(None, bootloader_kernel_args, None)
  994.                 except:
  995.                     self._d.msgbox(_(u"ERROR! Could not set bootloader kernel arguments! ")+bootloader_kernel_args)
  996.                 
  997.  
  998.     def set_timezone(self):
  999.     # This section will be for setting the timezone.
  1000.         zonepath = "/usr/share/zoneinfo"
  1001.         skiplist = ["zone.tab","iso3166.tab","posixrules"]
  1002.         while 1:
  1003.             tzlist = []
  1004.             for entry in os.listdir(zonepath):
  1005.                 if entry not in skiplist:
  1006.                     if os.path.isdir(zonepath + "/" + entry): entry += "/"
  1007.                     tzlist.append(entry)
  1008.             tzlist.sort()
  1009.             timezone_string = _(u"Please select the timezone for the new installation.  Entries ending with a / can be selected to reveal a sub-list of more specific locations. For example, you can select America/ and then Chicago.")
  1010.             code, tznum = self._d.menu(timezone_string, choices=self._dmenu_list_to_choices(tzlist), height=20, cancel="Back")
  1011.             if code == self._DLG_OK:
  1012.                 zonepath = os.path.join(zonepath,tzlist[int(tznum)-1])
  1013.                 if tzlist[int(tznum)-1][-1:] != "/": 
  1014.                     break
  1015.             else:
  1016.                 if zonepath == "/usr/share/zoneinfo": 
  1017.                     return
  1018.                 slashloc = zonepath[:-1].rfind("/")
  1019.                 zonepath = zonepath[:slashloc]
  1020.         try:
  1021.             self._install_profile.set_time_zone(None, zonepath[20:], None)
  1022.         except:
  1023.             self._d.msgbox(_(u"ERROR: Could not set that timezone!"))
  1024.  
  1025.     def set_networking(self):
  1026.     # This section will be for setting up network interfaces
  1027.         interfaces = self._install_profile.get_network_interfaces()
  1028.         CC_iface = self._client_profile.get_network_interface()
  1029.         if CC_iface and (CC_iface not in interfaces):
  1030.             #The CC has a network config that's not already there.  Preload it.
  1031.             CC_net_type = self._client_profile.get_network_type()
  1032.             if CC_net_type == 'dhcp':
  1033.                 try:
  1034.                     interfaces[CC_iface] = ('dhcp', self._client_profile.get_network_dhcp_options(), None)
  1035.                 except:
  1036.                     pass
  1037.             else:
  1038.                 try:
  1039.                     interfaces[CC_iface] = (self._client_profile.get_network_ip(), self._client_profile.get_network_broadcast(), self._client_profile.get_network_netmask())
  1040.                 except:
  1041.                     pass
  1042.             
  1043.         while 1:
  1044.             net_string1 = _(u"Here you will enter all of your network interface information for the new system.  You can either choose a network interface to edit, add a network interface, delete an interface, or edit the miscellaneous options such as hostname and proxy servers.")
  1045.             net_string2 = _(u"To setup your network interface, you can either use DHCP if enabled, or manually enter your network information.\n  DHCP (Dynamic Host Configuration Protocol) makes it possible to automatically receive networking information (IP address, netmask, broadcast address, gateway, nameservers etc.). This only works if you have a DHCP server in your network (or if your provider provides a DHCP service).  If you do not, you must enter the information manually.  Please select your networking configuration method:")
  1046.             choice_list = []
  1047.             for iface in interfaces:
  1048.                 if interfaces[iface][0] == 'dhcp':
  1049.                     choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1]))
  1050.                 else:
  1051.                     choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+_(u" Netmask: ")+interfaces[iface][2]))
  1052.             choice_list.append(("Add",_(u"Add a new network interface")))
  1053.             code, iface_choice = self._d.menu(net_string1, choices=choice_list, cancel=_(u"Save and Continue"), height=18, width=77)
  1054.             if code != self._DLG_OK:
  1055.                 try:
  1056.                     self._install_profile.set_network_interfaces(interfaces)
  1057.                 except:
  1058.                     self_d.msgbox(_(u"ERROR! Could not set the network interfaces!"))
  1059.                 break  #This should hopefully move the user down to part two of set_networking
  1060.             if iface_choice == "Add":
  1061.                 if self.local_install:
  1062.                     device_list = GLIUtility.get_eth_devices()
  1063.                     newchoice_list = []
  1064.                     for device in device_list:
  1065.                         if device not in interfaces:
  1066.                             newchoice_list.append((device, GLIUtility.get_interface_realname(device)))
  1067.                     newchoice_list.append((_(u"Other"),_(u"Type your own.")))
  1068.                     code, newnic = self._d.menu(_("Choose an interface from the list or Other to type your own if it was not detected."), choices=newchoice_list, width=75)
  1069.                 else:
  1070.                     newnic == _(u"Other")
  1071.                 if newnic == _(u"Other"):
  1072.                     code, newnic = self._d.inputbox(_(u"Enter name for new interface (eth0, ppp0, etc.)"))
  1073.                     if code != self._DLG_OK: 
  1074.                         continue
  1075.                     if newnic in interfaces:
  1076.                         self._d.msgbox(_(u"An interface with the name is already defined."))
  1077.                         continue
  1078.                 #create the interface in the data structure.
  1079.                 #interfaces[newnic] = ("", "", "")
  1080.                 #Change the Yes/No buttons to new labels for this question.
  1081.                 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
  1082.                 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
  1083.                 if self._d.yesno(net_string2, height=15, width=60) == self._DLG_YES: #DHCP
  1084.                     dhcp_options = ""
  1085.                     if self.advanced_mode:
  1086.                         code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list.  If you have none, just press Enter."), height=13, width=50)
  1087.                     interfaces[newnic] = ('dhcp', dhcp_options, None)
  1088.                 else:
  1089.                     network_type = 'static'
  1090.                     code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information)  Your broadcast address is probably your IP address with 255 as the last tuple.  Do not press Enter until all fields are complete!'),
  1091.                     ((_(u'Enter your IP address:'), 15),
  1092.                      (_(u'Enter your Broadcast address:'), 15),
  1093.                      (_(u'Enter your Netmask:'),15,'255.255.255.0')))
  1094.                     (ip_address, broadcast, netmask) = data[:-1].split('\n')
  1095.                     if code != self._DLG_OK: 
  1096.                         continue
  1097.                     #Set the info now that it's all gathered.
  1098.                     interfaces[newnic] = (ip_address, broadcast, netmask)
  1099.             else:  #they have chosen an interface, present them with edit/delete
  1100.                 #Change the Yes/No buttons to new labels for this question.
  1101.                 self._d.add_persistent_args(["--yes-label", _(u"Edit")])
  1102.                 self._d.add_persistent_args(["--no-label", _(u"Delete")])
  1103.                 if self._d.yesno(_(u"For interface %s, you can either edit the interface information (IP Address, Broadcast, Netmask) or Delete the interface.") % iface_choice) == self._DLG_YES:
  1104.                     #Edit
  1105.                     #Change the Yes/No buttons to new labels for this question.
  1106.                     self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
  1107.                     self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
  1108.                     if self._d.yesno(net_string2, height=15, width=60) == self._DLG_YES: #DHCP
  1109.                         dhcp_options = ""
  1110.                         if self.advanced_mode:
  1111.                             code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list.  If you have none, just press Enter."), height=13, width=50)
  1112.                         interfaces[iface_choice] = ('dhcp', dhcp_options, None)
  1113.                     else:
  1114.                         network_type = 'static'
  1115.                         code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information)  Your broadcast address is probably your IP address with 255 as the last tuple.  Do not press Enter until all fields are complete!'), 
  1116.                         ((_(u'Enter your IP address:'), 15, interfaces[iface_choice][0]),
  1117.                          (_(u'Enter your Broadcast address:'), 15, interfaces[iface_choice][1]),
  1118.                          (_(u'Enter your Netmask:'),15,interfaces[iface_choice][2])))
  1119.                         (ip_address, broadcast, netmask) = data[:-1].split('\n')
  1120.                         if code != self._DLG_OK: 
  1121.                             continue
  1122.                         #Set the info now that it's all gathered.
  1123.                         interfaces[iface_choice] = (ip_address, broadcast, netmask)
  1124.                 else:
  1125.                     #Delete
  1126.                     #Reset the Yes/No buttons
  1127.                     self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  1128.                     self._d.add_persistent_args(["--no-label", _(u"No")])
  1129.                     if self._d.yesno(_(u"Are you sure you want to remove the interface ") + iface_choice + "?") == self._DLG_YES:
  1130.                         del interfaces[iface_choice]
  1131.             
  1132.         #This section is for defining DNS servers, default routes/gateways, hostname, etc.
  1133.         #First ask for the default gateway device and IP
  1134.         interfaces = self._install_profile.get_network_interfaces()
  1135.         choice_list = []
  1136.         for iface in interfaces:
  1137.             if interfaces[iface][0] == 'dhcp':
  1138.                 choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1],0))
  1139.             else:
  1140.                 choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+_(u" Netmask: ")+interfaces[iface][2],0))
  1141.         net_string3 = _("To be able to surf on the internet, you must know which host shares the Internet connection. This host is called the gateway.  It is usually similar to your IP address, but ending in .1\nIf you have DHCP then just select your primary Internet interface (no IP will be needed)  Start by choosing which interface accesses the Internet:")
  1142.         if choice_list:
  1143.             code, gateway_iface = self._d.radiolist(net_string3, choices=choice_list, height=20, width=67)
  1144.             if (code == self._DLG_OK) and gateway_iface:  #They made a choice.  Ask the IP if not DHCP.
  1145.                 while interfaces[gateway_iface][0] != 'dhcp':
  1146.                     code, ip = self._d.inputbox(_(u"Enter the gateway IP address for ") + gateway_iface, init=interfaces[gateway_iface][0])
  1147.                     if code != self._DLG_OK:
  1148.                         break
  1149.                     if not GLIUtility.is_ip(ip):
  1150.                         self._d.msgbox(_(u"Invalid IP Entered!  Please try again."))
  1151.                         continue
  1152.                     try:
  1153.                         self._install_profile.set_default_gateway(None, ip,{'interface': gateway_iface})
  1154.                     except:
  1155.                         self._d.msgbox(_(u"ERROR! Coult not set the default gateway with IP %s for interface %s") % (ip, gateway_iface))
  1156.                     break
  1157.         #Now ask for the other info in a large form.
  1158.         error = True
  1159.         hostname = ""
  1160.         domainname = ""
  1161.         nisdomainname = ""
  1162.         primary_dns = ""
  1163.         backup_dns = ""
  1164.         http_proxy = ""
  1165.         ftp_proxy = ""
  1166.         rsync_proxy = ""
  1167.         while error:
  1168.             error = False
  1169.             if self.advanced_mode:
  1170.                 code, data = self._d.form(_(u'Fill out the remaining networking settings.  The hostname is manditory as that is the name of your computer.  Leave the other fields blank if you are not using them.  If using DHCP you do not need to enter DNS servers.  Do not press Enter until all fields are complete!'),
  1171.                 ((_(u'Enter your Hostname:'), 25, self._install_profile.get_hostname()),
  1172.                  (_(u'Enter your Domain Name:'), 25, self._install_profile.get_domainname()),
  1173.                  (_(u'Enter your NIS Domain Name:'),25,self._install_profile.get_nisdomainname()),
  1174.                  (_(u'Enter a primary DNS server:'),15),
  1175.                  (_(u'Enter a backup DNS server:'),15),
  1176.                  (_(u'Enter a HTTP Proxy IP:'), 15,self._install_profile.get_http_proxy()),
  1177.                  (_(u'Enter a FTP Proxy IP:'), 15, self._install_profile.get_ftp_proxy()), 
  1178.                  (_(u'Enter a RSYNC Proxy:'),15,self._install_profile.get_rsync_proxy())))
  1179.                 if code != self._DLG_OK:
  1180.                     return
  1181.                 (hostname, domainname, nisdomainname, primary_dns, backup_dns, http_proxy, ftp_proxy, rsync_proxy) = data[:-1].split('\n')
  1182.             else: #standard mode
  1183.                 code, data = self._d.form(_(u'Fill out the remaining networking settings.  The hostname is manditory as that is the name of your computer.  Leave the other fields blank if you are not using them.  If using DHCP you do not need to enter DNS servers.  Do not press Enter until all fields are complete!'),
  1184.                 ((_(u'Enter your Hostname:'), 25, self._install_profile.get_hostname()),
  1185.                  (_(u'Enter your Domain Name:'), 25, self._install_profile.get_domainname()),
  1186.                  (_(u'Enter a primary DNS server:'),15),
  1187.                  (_(u'Enter a backup DNS server:'),15)))
  1188.                 if code != self._DLG_OK:
  1189.                     return
  1190.                 (hostname, domainname, primary_dns, backup_dns) = data[:-1].split('\n')
  1191.             #Check the data before entering it.                
  1192.             if hostname:
  1193.                 if type(hostname) != str:
  1194.                     self._d.msgbox(_(u"Incorrect hostname!  It must be a string.  Not saved."))
  1195.                     error = True    
  1196.                 else:
  1197.                     try:            
  1198.                         self._install_profile.set_hostname(None, hostname, None)
  1199.                     except:
  1200.                         self._d.msgbox(_(u"ERROR! Could not set the hostname:")+hostname)
  1201.                         error = True
  1202.             if domainname:
  1203.                 if type(domainname) != str:
  1204.                     self._d.msgbox(_(u"Incorrect domainname!  It must be a string.  Not saved."))
  1205.                     error = True    
  1206.                 else:
  1207.                     try:            
  1208.                         self._install_profile.set_domainname(None, domainname, None)
  1209.                     except:
  1210.                         self._d.msgbox(_(u"ERROR! Could not set the domainname:")+domainname)
  1211.                         error = True
  1212.             if nisdomainname:
  1213.                 if type(nisdomainname) != str:
  1214.                     self._d.msgbox(_(u"Incorrect nisdomainname!  It must be a string.  Not saved."))
  1215.                     error = True    
  1216.                 else:
  1217.                     try:            
  1218.                         self._install_profile.set_nisdomainname(None, nisdomainname, None)
  1219.                     except:
  1220.                         self._d.msgbox(_(u"ERROR! Could not set the nisdomainname:")+nisdomainname)
  1221.                         error = True                    
  1222.             if primary_dns:
  1223.                 if not GLIUtility.is_ip(primary_dns):
  1224.                     self._d.msgbox(_(u"Incorrect Primary DNS Server! Not saved."))
  1225.                     error = True
  1226.                 else:
  1227.                     if backup_dns:
  1228.                         if not GLIUtility.is_ip(backup_dns):
  1229.                             self._d.msgbox(_(u"Incorrect Backup DNS Server! Not saved."))
  1230.                             error = True
  1231.                         else:
  1232.                             primary_dns = primary_dns + " " + backup_dns
  1233.                     try:            
  1234.                         self._install_profile.set_dns_servers(None, primary_dns, None)
  1235.                     except:
  1236.                         self._d.msgbox(_(u"ERROR! Could not set the DNS Servers:")+primary_dns)
  1237.                         error = True
  1238.             if http_proxy:
  1239.                 if not GLIUtility.is_uri(http_proxy):
  1240.                     self._d.msgbox(_(u"Incorrect HTTP Proxy! It must be a uri. Not saved."))
  1241.                     error = True
  1242.                 else:
  1243.                     try:
  1244.                         self._install_profile.set_http_proxy(None, http_proxy, None)
  1245.                     except:
  1246.                         self._d.msgbox(_(u"ERROR! Could not set the HTTP Proxy:")+http_proxy)
  1247.                         error = True                    
  1248.             if ftp_proxy:
  1249.                 if not GLIUtility.is_uri(ftp_proxy):
  1250.                     self._d.msgbox(_(u"Incorrect FTP Proxy! It must be a uri. Not saved."))
  1251.                     error = True
  1252.                 else:
  1253.                     try:
  1254.                         self._install_profile.set_ftp_proxy(None, ftp_proxy, None)
  1255.                     except:
  1256.                         self._d.msgbox(_(u"ERROR! Could not set the FTP Proxy:")+ftp_proxy)
  1257.                         error = True
  1258.             if rsync_proxy:
  1259.                 if not GLIUtility.is_uri(rsync_proxy):
  1260.                     self._d.msgbox(_(u"Incorrect RSYNC Proxy! It must be a uri. Not saved."))
  1261.                     error = True
  1262.                 else:
  1263.                     try:
  1264.                         self._install_profile.set_rsync_proxy(None, rsync_proxy, None)
  1265.                     except:
  1266.                         self._d.msgbox(_(u"ERROR! Could not set the RSYNC Proxy:")+rsync_proxy)
  1267.                         error = True
  1268.  
  1269.  
  1270.     def set_cron_daemon(self):
  1271.         cron_daemons = (("vixie-cron", _(u"Paul Vixie's cron daemon, fully featured, RECOMMENDED.")),
  1272.         ("dcron",_(u"A cute little cron from Matt Dillon.")), 
  1273.         ("fcron", _(u"A scheduler with extended capabilities over cron & anacron")), 
  1274.         ("None", _(u"Don't use a cron daemon. (NOT Recommended!)")))
  1275.         cron_string = _(u"A cron daemon executes scheduled commands. It is very handy if you need to execute some command regularly (for instance daily, weekly or monthly).  Gentoo offers three possible cron daemons: dcron, fcron and vixie-cron. Installing one of them is similar to installing a system logger. However, dcron and fcron require an extra configuration command, namely crontab /etc/crontab. If you don't know what to choose, use vixie-cron.  If doing a networkless install, choose vixie-cron.  Choose your cron daemon:")
  1276.         code, menuitem = self._d.menu(cron_string, choices=cron_daemons, height=21, width=77)
  1277.         if code == self._DLG_OK:
  1278.             if menuitem == "None": 
  1279.                 menuitem = ""
  1280.             self._install_profile.set_cron_daemon_pkg(None, menuitem, None)
  1281.  
  1282.     def set_logger(self):
  1283.         loggers = (("syslog-ng", _(u"An advanced system logger.")), 
  1284.         ("metalog", _(u"A Highly-configurable system logger.")), 
  1285.         ("syslogkd", _(u"The traditional set of system logging daemons.")))
  1286.         logger_string = _(u"Linux has an excellent history of logging capabilities -- if you want you can log everything that happens on your system in logfiles. This happens through the system logger. Gentoo offers several system loggers to choose from.  If you plan on using sysklogd or syslog-ng you might want to install logrotate afterwards as those system loggers don't provide any rotation mechanism for the log files.  If doing networkless, choose syslog-ng.  Choose a system logger:")
  1287.         code, menuitem = self._d.menu(logger_string, choices=loggers, height=21, width=68)
  1288.         if code == self._DLG_OK:
  1289.             self._install_profile.set_logging_daemon_pkg(None, menuitem, None)
  1290.  
  1291.     def set_extra_packages(self):
  1292.         #d.msgbox("This section is for selecting extra packages (pcmcia-cs, rp-pppoe, xorg-x11, etc.) and setting them up")
  1293.         if self._install_profile.get_install_packages():
  1294.             install_packages = self._install_profile.get_install_packages()
  1295.             if isinstance(install_packages, str):
  1296.                 install_packages = install_packages.split()
  1297.         else:
  1298.             install_packages = []
  1299.         package_list = self._install_profile.get_install_package_list()
  1300.         highlevel_menu = []
  1301.         for group in package_list:
  1302.             highlevel_menu.append( (group, package_list[group][0]) )
  1303.         highlevel_menu.append( ("Manual", "Type your own space-separated list of packages.") )
  1304.  
  1305.         while 1:
  1306.             extra_string1 = _(u"There are thousands of applications available to Gentoo users through Portage, Gentoo's package management system.  Select some of the more common ones below or add your own additional package list by choosing 'Manual'.")
  1307.             code, submenu = self._d.menu(extra_string1+ _(u"\nYour current package list is: ")+string.join(install_packages, ','), choices=highlevel_menu, cancel=_(u"Save and Continue"), width=70, height=23)
  1308.             if code != self._DLG_OK:  #Save and move on.
  1309.                 try:
  1310.                     packages = string.join(install_packages, ' ')
  1311.                     if packages:
  1312.                         self._install_profile.set_install_packages(None, packages, None)
  1313.                 except:
  1314.                     self._d.msgbox(_(u"ERROR! Could not set the install packages! List of packages:"))
  1315.                 return
  1316.             #Popular Desktop Applications
  1317.             choices_list = []
  1318.             #pkgs = {}
  1319.             
  1320.             #Special case first.
  1321.             if submenu == "Manual":
  1322.                 code, tmp_install_packages = self._d.inputbox(_(u"Enter a space-separated list of extra packages to install on the system"), init=string.join(install_packages, ' '), width=70) 
  1323.                 if code == self._DLG_OK:
  1324.                     install_packages = tmp_install_packages.split()
  1325.                 continue
  1326.                 
  1327.             #All other cases load pkgs and GRP
  1328.             pkgs = package_list[submenu][1]
  1329.             grp_list = GLIUtility.get_grp_pkgs_from_cd()
  1330.             for pkg in pkgs:
  1331.                 if pkg in grp_list:
  1332.                     choices_list.append((pkg, "(GRP) "+pkgs[pkg], int(pkg in install_packages)))
  1333.                 else:
  1334.                     choices_list.append((pkg, pkgs[pkg], int(pkg in install_packages)))
  1335.             code, choices = self._d.checklist(_(u"Choose from the listed packages.  If doing a networkless install, only choose (GRP) packages."), choices=choices_list, height=19, list_height=10, width=77)
  1336.             if code != self._DLG_OK: 
  1337.                 continue
  1338.             for pkg in pkgs:  #clear out packages from this list that are already in install_packages so that you can uncheck packages and they will be removed.  the ones that remain checked will be re-added.
  1339.                 for i, tmppkg in enumerate(install_packages):
  1340.                     if tmppkg == pkg:
  1341.                         del install_packages[i]
  1342.                     
  1343.             for package in choices:
  1344.                 install_packages.append(package)
  1345.                 #special cases for desktop environments
  1346.                 if package in ["xorg-x11", "gnome","kde","blackbox","enlightenment","fluxbox","xfce4"]:  #ask about X
  1347.                     #Reset the Yes/No buttons
  1348.                     self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  1349.                     self._d.add_persistent_args(["--no-label", _(u"No")])
  1350.                     if not self.advanced_mode or self._d.yesno(_(u"Do you want to start X on bootup?")) == self._DLG_YES:
  1351.                         services = self._install_profile.get_services() or 'xdm'
  1352.                         if isinstance(services, list):
  1353.                             services = string.join(services, ',')
  1354.                         if 'xdm' not in services:
  1355.                             services += ',xdm'
  1356.                         try:
  1357.                             self._install_profile.set_services(None, services, None)
  1358.                         except:
  1359.                             self._d.msgbox(_(u"ERROR! Could not set the services list."))
  1360.                     #rc.conf changes specific to packages.
  1361.                     if package == "gnome":
  1362.                         etc_files = self._install_profile.get_etc_files()
  1363.                         if not "rc.conf" in etc_files:
  1364.                             etc_files['rc.conf'] = {}
  1365.                         etc_files['rc.conf']['DISPLAYMANAGER'] = "gdm"
  1366.                         self._install_profile.set_etc_files(etc_files)
  1367.                     if package == "kde":
  1368.                         etc_files = self._install_profile.get_etc_files()
  1369.                         if not "rc.conf" in etc_files:
  1370.                             etc_files['rc.conf'] = {}
  1371.                         etc_files['rc.conf']['DISPLAYMANAGER'] = "kdm"
  1372.                         self._install_profile.set_etc_files(etc_files)
  1373.                     if package == "enlightenment":
  1374.                         etc_files = self._install_profile.get_etc_files()
  1375.                         if not "rc.conf" in etc_files:
  1376.                             etc_files['rc.conf'] = {}
  1377.                         etc_files['rc.conf']['DISPLAYMANAGER'] = "entrance"
  1378.                         self._install_profile.set_etc_files(etc_files)
  1379.                     if package == "fluxbox":
  1380.                         etc_files = self._install_profile.get_etc_files()
  1381.                         if not "rc.conf" in etc_files:
  1382.                             etc_files['rc.conf'] = {}
  1383.                         etc_files['rc.conf']['XSESSION'] = "fluxbox"
  1384.                         self._install_profile.set_etc_files(etc_files)    
  1385.                         
  1386.                         
  1387.  
  1388.     def set_services(self):
  1389.         if self._install_profile.get_services():
  1390.             services = self._install_profile.get_services()
  1391.             if isinstance(services, str):
  1392.                 services = services.split(',')
  1393.         else:
  1394.             services = []
  1395.         choice_list = [("alsasound", _(u"ALSA Sound Daemon"),int("alsasound" in services)),
  1396.         ("apache", _(u"Common web server (version 1.x)"),int("apache" in services)),
  1397.         ("apache2", _(u"Common web server (version 2.x)"),int("apache2" in services)),
  1398.         ("distccd", _(u"Distributed Compiling System"),int("distccd" in services)),
  1399.         ("esound", _(u"ESD Sound Daemon"),int("esound" in services)),
  1400.         ("hdparm", _(u"Hard Drive Tweaking Utility"),int("hdparm" in services)),
  1401.         ("local", _(u"Run scripts found in /etc/conf.d/local.start"),int("local" in services)),
  1402.         ("portmap", _(u"Port Mapping Service"),int("portmap" in services)),
  1403.         ("proftpd", _(u"Common FTP server"),int("proftpd" in services)),
  1404.         ("sshd", _(u"SSH Daemon (allows remote logins)"),int("sshd" in services)),
  1405.         ("xfs", _(u"X Font Server"),int("xfs" in services)),
  1406.         ("xdm", _(u"X Daemon"),int("xdm" in services)),
  1407.         (_(u"Other"),_(u"Manually specify your services in a comma-separated list."),0)]
  1408.         services_string = _(u"Choose the services you want started on bootup.  Note that depending on what packages are selected, some services listed will not exist.")
  1409.         code, services_list = self._d.checklist(services_string, choices=choice_list, height=21, list_height=12, width=77)
  1410.         if code != self._DLG_OK:
  1411.             return
  1412.         services = []
  1413.         for service in services_list:
  1414.             services.append(service)
  1415.         if _(u"Other") in services_list:
  1416.             code, services = self._d.inputbox(_(u"Enter a comma-separated list of services to start on boot"), init=string.join(services, ','))
  1417.         if code != self._DLG_OK: 
  1418.             return
  1419.         try:
  1420.             services = string.join(services, ',')
  1421.             if services:
  1422.                 self._install_profile.set_services(None, services, None)
  1423.         except:
  1424.             self._d.msgbox(_(u"ERROR! Could not set the services list."))
  1425.             return
  1426.         
  1427.     def set_rc_conf(self):
  1428.     # This section is for editing /etc/rc.conf
  1429.         if not self.advanced_mode:
  1430.             return
  1431.         etc_files = self._install_profile.get_etc_files()
  1432.         keymap = ""
  1433.         windowkeys = ""
  1434.         ext_keymap = ""
  1435.         font = ""
  1436.         trans = ""
  1437.         clock = ""
  1438.         editor = ""
  1439.         disp_manager = ""
  1440.         xsession = ""
  1441.         rc_string1 = _(u"Additional configuration settings for Advanced users (rc.conf)\nHere are some other variables you can set in various configuration files on the new system.  If you don't know what a variable does, don't change it!")
  1442.         menulist = [("KEYMAP",_(u"Use KEYMAP to specify the default console keymap.")),
  1443.         ("SET_WINDOWSKEYS", _(u"Decision to first load the 'windowkeys' console keymap")),
  1444.         ("EXTENDED_KEYMAPS", _(u"maps to load for extended keyboards.  Most users will leave this as is.")),
  1445.         ("CONSOLEFONT", _(u"Specifies the default font that you'd like Linux to use on the console.")),
  1446.         ("CONSOLETRANSLATION", _(u"The charset map file to use.")),
  1447.         ("CLOCK", _(u"Set the clock to either UTC or local")),
  1448.         ("EDITOR", _(u"Set EDITOR to your preferred editor.")),
  1449.         ("DISPLAYMANAGER", _(u"What display manager do you use ?  [ xdm | gdm | kdm | entrance ]")),
  1450.         ("XSESSION", _(u"a new variable to control what window manager to start default with X"))]
  1451.         while 1:
  1452.             code, variable = self._d.menu(rc_string1, choices=menulist, cancel=_(u"Save and Continue"), width=77, height=19)
  1453.             if code != self._DLG_OK: 
  1454.                 break
  1455.             if variable == "KEYMAP":
  1456.                 keymap_list = GLIUtility.generate_keymap_list()
  1457.                 code, keymap = self._d.menu(_(u"Choose your desired keymap:"), choices=self._dmenu_list_to_choices(keymap_list), height=19)
  1458.                 if code != self._DLG_OK:
  1459.                     continue
  1460.                 keymap = keymap_list[int(keymap)-1]
  1461.                 
  1462.             elif variable == "SET_WINDOWSKEYS":
  1463.                 #Reset the Yes/No buttons
  1464.                 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  1465.                 self._d.add_persistent_args(["--no-label", _(u"No")])
  1466.                 if self._d.yesno(_(u"Should we first load the 'windowkeys' console keymap?  Most x86 users will say 'yes' here.  Note that non-x86 users should leave it as 'no'.")) == self._DLG_YES:
  1467.                     windowkeys = "yes"
  1468.                 else:
  1469.                     windowkeys = "no"
  1470.             elif variable == "EXTENDED_KEYMAPS":
  1471.                 code, ext_keymap = self._d.inputbox(_(u"This sets the maps to load for extended keyboards.  Most users will leave this as is.  Enter new value for EXTENDED_KEYMAPS"), width=60)
  1472.             elif variable == "CONSOLEFONT":
  1473.                 font_list = GLIUtility.generate_consolefont_list()
  1474.                 code, font = self._d.menu(_(u"Choose your desired console font:"), choices=self._dmenu_list_to_choices(font_list), height=19)
  1475.                 if code != self._DLG_OK:
  1476.                     continue
  1477.                 font = font_list[int(font)-1]
  1478.             elif variable == "CONSOLETRANSLATION":
  1479.                 trans_list = GLIUtility.generate_consoletranslation_list()
  1480.                 code, trans = self._d.menu(_(u"Choose your desired console translation:"), choices=self._dmenu_list_to_choices(trans_list), height=19)
  1481.                 if code != self._DLG_OK:
  1482.                     continue
  1483.                 trans = trans_list[int(trans)-1]
  1484.             elif variable == "CLOCK":
  1485.                 #Change the Yes/No buttons to new labels for this question.
  1486.                 self._d.add_persistent_args(["--yes-label", "UTC"])
  1487.                 self._d.add_persistent_args(["--no-label", "local"])
  1488.                 if self._d.yesno(_(u"Should CLOCK be set to UTC or local?  Unless you set your timezone to UTC you will want to choose local.")) == self._DLG_YES:
  1489.                     clock = "UTC"
  1490.                 else:
  1491.                     clock = "local"
  1492.             elif variable == "EDITOR":
  1493.                 choice_list = [("/bin/nano", _(u"Default editor.")), ("/usr/bin/vim", _(u"vi improved editor.")), ("/usr/bin/emacs", _(u"The emacs editor."))]
  1494.                 code, editor = self._d.menu(_(u"Choose your default editor: "), choices=choice_list)
  1495.             elif variable == "DISPLAYMANAGER":
  1496.                 choice_list = [("xdm", _(u"X Display Manager")), 
  1497.                 ("gdm", _(u"Gnome Display Manager")), 
  1498.                 ("kdm", _(u"KDE Display Manager")), 
  1499.                 ("entrance", _(u"Login Manager for Enlightenment"))]
  1500.                 code, disp_manager = self._d.menu(_(u"Choose your desired display manager to use when starting X (note you must make sure that package also gets installed for it to work):"), choices=choice_list, width=65)
  1501.             elif variable == "XSESSION":
  1502.                 code, xsession = self._d.inputbox(_(u"Choose what window manager you want to start default with X if run with xdm, startx, or xinit. (common options are Gnome or Xsession:"), width=65, height=12)
  1503.             
  1504.         if not "conf.d/keymaps" in etc_files: 
  1505.             if keymap or windowkeys or ext_keymap:
  1506.                 etc_files['conf.d/keymaps'] = {}
  1507.         if not "conf.d/consolefont" in etc_files: 
  1508.             if font or trans:
  1509.                 etc_files['conf.d/consolefont'] = {}
  1510.         if not "conf.d/clock" in etc_files: 
  1511.             if clock:
  1512.                 etc_files['conf.d/clock'] = {}
  1513.         if not "rc.conf" in etc_files: 
  1514.             if editor or disp_manager or xsession:
  1515.                 etc_files['rc.conf'] = {}
  1516.         if keymap:
  1517.             etc_files['conf.d/keymaps']['KEYMAP'] = keymap
  1518.         if windowkeys:
  1519.             etc_files['conf.d/keymaps']['SET_WINDOWSKEYS'] = windowkeys
  1520.         if ext_keymap:
  1521.             etc_files['conf.d/keymaps']['EXTENDED_KEYMAPS'] = ext_keymap
  1522.         if font:    
  1523.             etc_files['conf.d/consolefont']['CONSOLEFONT'] = font
  1524.         if trans:
  1525.             etc_files['conf.d/consolefont']['CONSOLETRANSLATION'] = trans
  1526.         if clock:
  1527.             etc_files['conf.d/clock']['CLOCK'] = clock
  1528.         if editor:
  1529.             etc_files['rc.conf']['EDITOR'] = editor
  1530.         if disp_manager:
  1531.             etc_files['rc.conf']['DISPLAYMANAGER'] = disp_manager
  1532.         if xsession:
  1533.             etc_files['rc.conf']['XSESSION'] = xsession
  1534.         self._install_profile.set_etc_files(etc_files)
  1535.     
  1536.     def set_root_password(self):
  1537.     # The root password will be set here
  1538.         while 1:
  1539.             code, passwd1 = self._d.passwordbox(_(u"Please enter your desired password for the root account.  (note it will not show the password.  Also do not try to use backspace.):"))
  1540.             if code != self._DLG_OK: 
  1541.                 return
  1542.             code, passwd2 = self._d.passwordbox(_(u"Enter the new root password again for confirmation"))
  1543.             if code != self._DLG_OK: 
  1544.                 return
  1545.             if passwd1 != passwd2:
  1546.                 self._d.msgbox(_(u"The passwords do not match.  Please try again or cancel."))
  1547.             else:
  1548.                 try:
  1549.                     self._install_profile.set_root_pass_hash(None, GLIUtility.hash_password(passwd1), None)
  1550.                 except:
  1551.                     self._d.msgbox(_(u"ERROR! Could not set the new system root password!"))
  1552.                 self._d.msgbox(_(u"Password saved.  Press Enter to continue."))
  1553.                 return
  1554.  
  1555.     def set_additional_users(self):
  1556.     # This section will be for adding non-root users
  1557.         users = {}
  1558.         for user in self._install_profile.get_users():
  1559.             users[user[0]] = (user[0], user[1], user[2], user[3], user[4], user[5], user[6])
  1560.         while 1:
  1561.             menu_list = []
  1562.             for user in users:
  1563.                 menu_list.append(user)
  1564.             menu_list.sort()
  1565.             menu_list.append(_(u"Add user"))
  1566.             users_string1 = _(u"Working as root on a Unix/Linux system is dangerous and should be avoided as much as possible. Therefore it is strongly recommended to add a user for day-to-day use.  Choose a user to edit:")
  1567.             code, menuitem = self._d.menu(users_string1, choices=self._dmenu_list_to_choices(menu_list), cancel="Save and Continue", height=19)
  1568.             if code != self._DLG_OK:
  1569.                 #if self._d.yesno("Do you want to save changes?") == self._DLG_YES:
  1570.                 tmpusers = []
  1571.                 for user in users:
  1572.                     tmpusers.append(users[user])
  1573.                 try:
  1574.                     self._install_profile.set_users(tmpusers)
  1575.                 except:
  1576.                     self._d.msgbox(_(u"ERROR! Could not set the additional users!"))
  1577.                 break
  1578.             menuitem = menu_list[int(menuitem)-1]
  1579.             if menuitem == _(u"Add user"):
  1580.                 code, newuser = self._d.inputbox(_(u"Enter the username for the new user"))
  1581.                 if code != self._DLG_OK: 
  1582.                     continue
  1583.                 if newuser in users:
  1584.                     self._d.msgbox(_(u"A user with that name already exists"))
  1585.                     continue
  1586.                 code, passwd1 = self._d.passwordbox(_(u"Enter the new password for user ")+ newuser)
  1587.                 code, passwd2 = self._d.passwordbox(_(u"Enter the new password again for confirmation"))
  1588.                 if code == self._DLG_OK: 
  1589.                     if passwd1 != passwd2:
  1590.                         self._d.msgbox(_(u"The passwords do not match! Go to the menu and try again."))
  1591.                 #Create the entry for the new user
  1592.                 new_user = [newuser, GLIUtility.hash_password(passwd1), ('users',), '/bin/bash', '/home/' + newuser, '', '']
  1593.                 users[newuser] = new_user
  1594.                 menuitem = newuser
  1595.             while 1:
  1596.                 menulist = [_(u"Password"), _(u"Group Membership"), _(u"Shell"), _(u"Home Directory"), _(u"UID"), _(u"Comment"), _(u"Delete")]
  1597.                 code, menuitem2 = self._d.menu(_(u"Choose an option for user ") + menuitem, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
  1598.                 if code != self._DLG_OK: 
  1599.                     break
  1600.                 menuitem2 = menulist[int(menuitem2)-1]
  1601.                 if menuitem2 == _(u"Password"):
  1602.                     code, passwd1 = self._d.passwordbox(_(u"Enter the new password"))
  1603.                     if code != self._DLG_OK: 
  1604.                         continue
  1605.                     code, passwd2 = self._d.passwordbox(_(u"Enter the new password again"))
  1606.                     if code != self._DLG_OK: 
  1607.                         continue
  1608.                     if passwd1 != passwd2:
  1609.                         self._d.msgbox(_(u"The passwords do not match! Try again."))
  1610.                         continue
  1611.                     self._d.msgbox(_(u"Password saved.  Press Enter to continue."))
  1612.                     users[menuitem][1] = GLIUtility.hash_password(passwd1)
  1613.                 elif menuitem2 == _(u"Group Membership"):
  1614.                     prechk = users[menuitem][2]
  1615.                     choice_list = [("users", _(u"The usual group for normal users."), int("users" in prechk)),
  1616.                     ("wheel", _(u"Allows users to attempt to su to root."), int("wheel" in prechk)),
  1617.                     ("audio", _(u"Allows access to audio devices."), int("audio" in prechk)),
  1618.                     ("games", _(u"Allows access to games."), int("games" in prechk)),
  1619.                     ("apache", _(u"For users who know what they're doing only."), int("apache" in prechk)),
  1620.                     ("cdrom", _(u"For users who know what they're doing only."), int("cdrom" in prechk)),
  1621.                     ("ftp", _(u"For users who know what they're doing only."), int("ftp" in prechk)),
  1622.                     ("video", _(u"For users who know what they're doing only."), int("video" in prechk)),
  1623.                     (_(u"Other"), _(u"Manually specify your groups in a comma-separated list."), 0)]
  1624.                     users_string2 = _(u"Select which groups you would like the user %s to be in." % menuitem)
  1625.                     code, group_list = self._d.checklist(users_string2, choices=choice_list, height=19, list_height=10, width=77)
  1626.                     if code != self._DLG_OK:
  1627.                         break
  1628.                     groups = ""
  1629.                     for group in group_list:
  1630.                         groups += group + ","
  1631.                     if groups:
  1632.                         groups = groups[:-1]
  1633.                     if _(u"Other") in group_list:
  1634.                         code, groups = self._d.inputbox(_(u"Enter a comma-separated list of groups the user is to be in"), init=",".join(users[menuitem][2]))
  1635.                         if code != self._DLG_OK: continue
  1636.                     users[menuitem][2] = string.split(groups, ",")
  1637.                 elif menuitem2 == _(u"Shell"):
  1638.                     code, shell = self._d.inputbox(_(u"Enter the shell you want the user to use.  default is /bin/bash.  "), init=users[menuitem][3])
  1639.                     if code != self._DLG_OK: 
  1640.                         continue
  1641.                     users[menuitem][3] = shell
  1642.                 elif menuitem2 == _(u"Home Directory"):
  1643.                     code, homedir = self._d.inputbox(_(u"Enter the user's home directory. default is /home/username.  "), init=users[menuitem][4])
  1644.                     if code != self._DLG_OK: 
  1645.                         continue
  1646.                     users[menuitem][4] = homedir
  1647.                 elif menuitem2 == _(u"UID"):
  1648.                     code, uid = self._d.inputbox(_(u"Enter the user's UID. If left blank the system will choose a default value (this is recommended)."), init=users[menuitem][5], height=11, width=55)
  1649.                     if code != self._DLG_OK: 
  1650.                         continue
  1651.                     if type(uid) != int: 
  1652.                         continue
  1653.                     users[menuitem][5] = uid
  1654.                 elif menuitem2 == _(u"Comment"):
  1655.                     code, comment = self._d.inputbox(_(u"Enter the user's comment.  This is completely optional."), init=users[menuitem][6])
  1656.                     if code != self._DLG_OK: 
  1657.                         continue
  1658.                     users[menuitem][6] = comment
  1659.                 elif menuitem2 == _(u"Delete"):
  1660.                     #Reset the Yes/No buttons
  1661.                     self._d.add_persistent_args(["--yes-label", _(u"Yes")])
  1662.                     self._d.add_persistent_args(["--no-label", _(u"No")])
  1663.                     if self._d.yesno(_(u"Are you sure you want to delete the user ") + menuitem + "?") == self._DLG_YES:
  1664.                         del users[menuitem]
  1665.                         break
  1666.  
  1667.             
  1668.     def save_install_profile(self, xmlfilename="", askforfilename=True):
  1669.         code = 0
  1670.         filename = xmlfilename
  1671.         if askforfilename:
  1672.             code, filename = self._d.inputbox(_(u"Enter a filename for the XML file"), init=xmlfilename)
  1673.             if code != self._DLG_OK or not filename: 
  1674.                 return None
  1675.         if GLIUtility.is_file(filename):
  1676.             if not self._d.yesno(_(u"The file %s already exists. Do you want to overwrite it?") % filename) == self._DLG_YES:
  1677.                 return None
  1678.         configuration = open(filename ,"w")
  1679.         configuration.write(self._install_profile.serialize())
  1680.         configuration.close()
  1681.         return filename
  1682.     def show_settings(self):
  1683.         settings = _(u"Look carefully at the following settings to check for mistakes.\nThese are the installation settings you have chosen:\n\n")
  1684.         #Partitioning
  1685.         settings += "Partitioning:  \n  Key: Minor, Pri/Ext, Filesystem, MkfsOpts, Mountpoint, MountOpts, Size.\n"
  1686.         devices = self._install_profile.get_partition_tables()
  1687.         drives = devices.keys()
  1688.         drives.sort()
  1689.         for drive in drives:
  1690.             settings += "  Drive: " + drive + devices[drive].get_model() + "\n"
  1691.             partlist = devices[drive].get_ordered_partition_list()
  1692.             tmpparts = devices[drive].get_partitions()
  1693.             for part in partlist:
  1694.                 tmppart = tmpparts[part]
  1695.                 entry = "    "
  1696.                 if tmppart.get_type() == "free":
  1697.                     #partschoice = "New"
  1698.                     entry += _(u" - Unallocated space (")
  1699.                     if tmppart.is_logical():
  1700.                         entry += _(u"logical, ")
  1701.                     entry += str(tmppart.get_mb()) + "MB)"
  1702.                 elif tmppart.get_type() == "extended":
  1703.                     entry += str(int(tmppart.get_minor()))
  1704.                     entry += _(u" - Extended Partition (") + str(tmppart.get_mb()) + "MB)"
  1705.                 else:
  1706.                     entry += str(int(tmppart.get_minor())) + " - "
  1707.                     if tmppart.is_logical():
  1708.                         entry += _(u"Logical (")
  1709.                     else:
  1710.                         entry += _(u"Primary (")
  1711.                     entry += tmppart.get_type() + ", "
  1712.                     entry += (tmppart.get_mkfsopts() or "none") + ", "
  1713.                     entry += (tmppart.get_mountpoint() or "none") + ", "
  1714.                     entry += (tmppart.get_mountopts() or "none") + ", "
  1715.                     entry += str(tmppart.get_mb()) + "MB)"
  1716.                 settings += entry + "\n"
  1717.             
  1718.         #Network Mounts:
  1719.         network_mounts = copy.deepcopy(self._install_profile.get_network_mounts())
  1720.         settings += "\nNetwork Mounts: \n"
  1721.         for mount in network_mounts:
  1722.             settings += "  "+mount['host']+":"+mount['export']+"\n"
  1723.             
  1724.         #Install Stage:
  1725.         settings += "\nInstall Stage: " + str(self._install_profile.get_install_stage()) + "\n"
  1726.         if self._install_profile.get_dynamic_stage3():
  1727.             settings += "  Tarball will be generated on the fly from the CD.\n"
  1728.         else:
  1729.             settings += "  Tarball URI: " + self._install_profile.get_stage_tarball_uri() + "\n"
  1730.             
  1731.         #Portage Tree Sync Type:
  1732.         settings += "\nPortage Tree Sync Type: " + self._install_profile.get_portage_tree_sync_type() + "\n"
  1733.         if self._install_profile.get_portage_tree_sync_type() == "snapshot":
  1734.             settings += "  Portage snapshot URI: " + self._install_profile.get_portage_tree_snapshot_uri() + "\n"
  1735.             
  1736.         #Kernel Settings:
  1737.         settings += "\nKernel Settings:\n"
  1738.         settings += "  Kernel Sources: " + self._install_profile.get_kernel_source_pkg() + "\n"
  1739.         if self._install_profile.get_kernel_source_pkg() != "livecd-kernel":
  1740.             settings += "  Kernel Build Method: " + self._install_profile.get_kernel_build_method() + "\n"
  1741.             if self._install_profile.get_kernel_build_method() == "genkernel":
  1742.                 settings += "  Kernel Bootsplash Option: " + str(self._install_profile.get_kernel_bootsplash()) + "\n"
  1743.         if self._install_profile.get_kernel_config_uri():
  1744.             settings += "  Kernel Configuration URI: " + self._install_profile.get_kernel_config_uri() + "\n"
  1745.                 
  1746.         #Bootloader Settings:
  1747.         settings += "\nBootloader Settings:\n"
  1748.         settings += "  Bootloader package: " + self._install_profile.get_boot_loader_pkg() + "\n"
  1749.         if self._install_profile.get_boot_loader_pkg() != "none":
  1750.             settings += "  Install bootloader to MBR: " + str(self._install_profile.get_boot_loader_mbr()) + "\n"
  1751.             settings += "  Bootloader kernel arguments: " +self._install_profile.get_bootloader_kernel_args() + "\n"
  1752.             
  1753.         #Timezone:
  1754.         settings += "\nTimezone: " + self._install_profile.get_time_zone() + "\n"
  1755.         
  1756.         #Networking Settings:
  1757.         settings += "\nNetworking Settings: \n"
  1758.         interfaces = self._install_profile.get_network_interfaces()
  1759.         for iface in interfaces:
  1760.             if interfaces[iface][0] == 'dhcp':
  1761.                 settings += "  " + iface + _(u":  Settings: DHCP. Options: ") + interfaces[iface][1] + "\n"
  1762.             else:
  1763.                 settings += "  " + iface + _(u"IP: ") + interfaces[iface][0] + _(u" Broadcast: ") + interfaces[iface][1] + _(u" Netmask: ") + interfaces[iface][2] + "\n"
  1764.         default_gateway = self._install_profile.get_default_gateway()
  1765.         if default_gateway:
  1766.             settings += "  Default Gateway: " + default_gateway[0] + "/" + default_gateway[1] + "\n"
  1767.         settings += "  Hostname: " + self._install_profile.get_hostname() + "\n"
  1768.         if self._install_profile.get_domainname():
  1769.             settings += "  Domainname: " +self._install_profile.get_domainname() + "\n"
  1770.         if self._install_profile.get_nisdomainname():
  1771.             settings += "  NIS Domainname: " +self._install_profile.get_nisdomainname() + "\n"
  1772.         if self._install_profile.get_dns_servers():
  1773.             for dns_server in self._install_profile.get_dns_servers():
  1774.                 settings += "  DNS Server: " +dns_server + "\n"
  1775.         if self._install_profile.get_http_proxy():
  1776.             settings += "  HTTP Proxy: " +self._install_profile.get_http_proxy() + "\n"
  1777.         if self._install_profile.get_ftp_proxy():
  1778.             settings += "  FTP Proxy: " +self._install_profile.get_ftp_proxy() + "\n"
  1779.         if self._install_profile.get_rsync_proxy():
  1780.             settings += "  RSYNC Proxy: " +self._install_profile.get_rsync_proxy() + "\n"
  1781.             
  1782.         #Cron Daemon:
  1783.         settings += "\nCron Daemon: " + self._install_profile.get_cron_daemon_pkg() + "\n"
  1784.         
  1785.         #Logger:
  1786.         settings += "\nLogging Daemon: " + self._install_profile.get_logging_daemon_pkg() + "\n"
  1787.         
  1788.         #Extra packages:
  1789.         if self._install_profile.get_install_packages():
  1790.             install_packages = self._install_profile.get_install_packages()
  1791.         else:
  1792.             install_packages = []
  1793.         settings += "\nExtra Packages: "
  1794.         for package in install_packages:
  1795.             settings += package + " "
  1796.         settings += "\n"
  1797.         #Services:
  1798.         if self._install_profile.get_services():
  1799.             services = self._install_profile.get_services()
  1800.         else:
  1801.             services = []
  1802.         settings += "\nAdditional Services: "
  1803.         for service in services:
  1804.             settings += service + " "
  1805.         settings += "\n"
  1806.         
  1807.         #Other Configuration Settings (rc.conf):
  1808.         #Make.conf Settings:
  1809.         settings += "\nConfiguration Files Settings:\n"
  1810.         etc_files = self._install_profile.get_etc_files()
  1811.         for etc_file in etc_files:
  1812.             settings += "  File:" + etc_file + "\n"
  1813.             if isinstance(etc_files[etc_file], dict):
  1814.                 for name in etc_files[etc_file]:
  1815.                     settings += "    Variable: " + name + "   Value: " + etc_files[etc_file][name] + "\n"
  1816.             else:
  1817.                 for entry in etc_files[etc_file]:
  1818.                     settings += "    Value: "+ entry + "\n"
  1819.         
  1820.         #Additional Users:
  1821.         settings += "\nAdditional Users:\n"
  1822.         users = {}
  1823.         for user in self._install_profile.get_users():
  1824.             users[user[0]] = (user[0], user[1], user[2], user[3], user[4], user[5], user[6])
  1825.         for user in users:
  1826.             settings += "  Username: " + user
  1827.             settings += "\n    Group Membership: " + string.join(users[user][2], ",")
  1828.             settings += "\n    Shell: " + users[user][3]
  1829.             settings += "\n    Home Directory: " + users[user][4]
  1830.             if users[user][5]:
  1831.                 settings += "\n    User Id: " + users[user][5]
  1832.             if users[user][6]:
  1833.                 settings += "\n    User Comment: " + users[user][6]
  1834.  
  1835.         self._d.scrollbox(settings, height=20, width=77, title=_(u"A Review of your settings"))
  1836.